Convert a nested list to inactive with cumulative concatenation

I would like to convert a nested list as follows:

l <- list(A=list(a=list(1),b=list(2)), B=list(cd=list(c=list(3,4,5),d=list(6,7,8)),e=list(c(9,10)))) 

to the list

 o <- list(A=c(1,2),Aa=1,Ab=2,B=c(3:10), B.cd=c(3:8),B.cd.c=c(3:5),B.cd.d=c(6:8),Be=c(9:10)) 

At each level of the list, values ​​from nested lists must be combined.

+6
r
source share
1 answer

Obviously, the case is for a recursive function, but getting the return values ​​for the correct list is complicated. Here is the function that will do this; he does not receive the names completely correct, but this is easily fixed afterwards.

 unnest <- function(x) { if(is.null(names(x))) { list(unname(unlist(x))) } else { c(list(all=unname(unlist(x))), do.call(c, lapply(x, unnest))) } } 

Exiting unnest(l) equals

 $all [1] 1 2 3 4 5 6 7 8 9 10 $A.all [1] 1 2 $Aa [1] 1 $Ab [1] 2 $B.all [1] 3 4 5 6 7 8 9 10 $B.cd.all [1] 3 4 5 6 7 8 $B.cd.c [1] 3 4 5 $B.cd.d [1] 6 7 8 $Be [1] 9 10 

and can be massaged into the desired result using

 out <- unnest(l) names(out) <- sub("\\.*all", "", names(out)) out[-1] 

To avoid overwriting when there is only one item, try

 unnest2 <- function(x) { if(is.null(names(x)) | length(x)==1) { list(unname(unlist(x))) } else { c(list(all=unname(unlist(x))), do.call(c, lapply(x, unnest2))) } } 
+7
source share

All Articles