I have functions that generate lists objects of class "foo" and lists of lists of these, of class "foolist", similar to what is shown below. How can I flatten something like this to remove the top-level list structure, i.e., return a single-level list of "foo" objects, of class "foolist"? foo <- function(n) { result <- list(x=sample(1:10,n), y=sample(1:10,n)) class(result) <- "foo" result } multifoo <- function(vec, label, ...) { result <- lapply(vec, foo, ...) names(result) <- paste0(label, vec) class(result) <- "foolist" result } foo1 <- multifoo(1:2, "A") foo2 <- multifoo(1:2, "B") mfoo <- list(A=foo1, B=foo2) str(mfoo, 2) > str(mfoo, 2) List of 2 $ A:List of 2 ..$ A1:List of 2 .. ..- attr(*, "class")= chr "foo" ..$ A2:List of 2 .. ..- attr(*, "class")= chr "foo" ..- attr(*, "class")= chr "foolist" $ B:List of 2 ..$ B1:List of 2 .. ..- attr(*, "class")= chr "foo" ..$ B2:List of 2 .. ..- attr(*, "class")= chr "foo" ..- attr(*, "class")= chr "foolist" In this case, what is wanted is a single-level list, of 4 foo objects, A1, A2, B1, B2, all of class "foolist" -- Michael Friendly Email: friendly AT yorku DOT ca Professor, Psychology Dept. & Chair, Quantitative Methods York University Voice: 416 736-2100 x66249 Fax: 416 736-5814 4700 Keele Street Web: http://www.datavis.ca Toronto, ONT M3J 1P3 CANADA
unlist(mfoo, recursive = FALSE) gets you pretty close. Best, Ista On Thu, Oct 17, 2013 at 9:15 AM, Michael Friendly <friendly at yorku.ca> wrote:> I have functions that generate lists objects of class "foo" and lists of > lists of these, of class > "foolist", similar to what is shown below. > > How can I flatten something like this to remove the top-level list > structure, i.e., > return a single-level list of "foo" objects, of class "foolist"? > > foo <- function(n) { > result <- list(x=sample(1:10,n), y=sample(1:10,n)) > class(result) <- "foo" > result > } > > multifoo <- function(vec, label, ...) { > result <- lapply(vec, foo, ...) > names(result) <- paste0(label, vec) > class(result) <- "foolist" > result > } > > foo1 <- multifoo(1:2, "A") > foo2 <- multifoo(1:2, "B") > > mfoo <- list(A=foo1, B=foo2) > > str(mfoo, 2) > >> str(mfoo, 2) > List of 2 > $ A:List of 2 > ..$ A1:List of 2 > .. ..- attr(*, "class")= chr "foo" > ..$ A2:List of 2 > .. ..- attr(*, "class")= chr "foo" > ..- attr(*, "class")= chr "foolist" > $ B:List of 2 > ..$ B1:List of 2 > .. ..- attr(*, "class")= chr "foo" > ..$ B2:List of 2 > .. ..- attr(*, "class")= chr "foo" > ..- attr(*, "class")= chr "foolist" > > In this case, what is wanted is a single-level list, of 4 foo objects, A1, > A2, B1, B2, > all of class "foolist" > > -- > Michael Friendly Email: friendly AT yorku DOT ca > Professor, Psychology Dept. & Chair, Quantitative Methods > York University Voice: 416 736-2100 x66249 Fax: 416 736-5814 > 4700 Keele Street Web: http://www.datavis.ca > Toronto, ONT M3J 1P3 CANADA > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
On 17/10/2013 9:15 AM, Michael Friendly wrote:> I have functions that generate lists objects of class "foo" and lists of > lists of these, of class > "foolist", similar to what is shown below.You can use c() to join lists. So in the example below, c(mfoo$A, mfoo$B) will give you a list with the components you want, though the class won't be set. More generally, do.call(c, unname(mfoo)) will join any number of components. (Without unname(), the names at the top level will be combined with the component names; maybe you'd actually want that, but your example didn't do it.) This won't work if your list doesn't have the regular "list of lists" structure, e.g. if it mixes foo objects with foolist objects at the same level. Then you probably need a more complicated recursive approach. You might be able to do it with rapply(). Duncan Murdoch> > How can I flatten something like this to remove the top-level list > structure, i.e., > return a single-level list of "foo" objects, of class "foolist"? > > foo <- function(n) { > result <- list(x=sample(1:10,n), y=sample(1:10,n)) > class(result) <- "foo" > result > } > > multifoo <- function(vec, label, ...) { > result <- lapply(vec, foo, ...) > names(result) <- paste0(label, vec) > class(result) <- "foolist" > result > } > > foo1 <- multifoo(1:2, "A") > foo2 <- multifoo(1:2, "B") > > mfoo <- list(A=foo1, B=foo2) > > str(mfoo, 2) > > > str(mfoo, 2) > List of 2 > $ A:List of 2 > ..$ A1:List of 2 > .. ..- attr(*, "class")= chr "foo" > ..$ A2:List of 2 > .. ..- attr(*, "class")= chr "foo" > ..- attr(*, "class")= chr "foolist" > $ B:List of 2 > ..$ B1:List of 2 > .. ..- attr(*, "class")= chr "foo" > ..$ B2:List of 2 > .. ..- attr(*, "class")= chr "foo" > ..- attr(*, "class")= chr "foolist" > > In this case, what is wanted is a single-level list, of 4 foo objects, > A1, A2, B1, B2, > all of class "foolist" >