Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

conversion of nested list to unnested with cumulative concatenation

Tags:

r

I would like to convert nested list like this:

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))))

into list

o <- list(A=c(1,2),A.a=1,A.b=2,B=c(3:10),
          B.cd=c(3:8),B.cd.c=c(3:5),B.cd.d=c(6:8),B.e=c(9:10))

At each list level values from nested lists should be concatenated.

like image 960
Wojciech Sobala Avatar asked Mar 09 '11 16:03

Wojciech Sobala


People also ask

How do I merge nested lists in python?

First, flatten the nested lists. Take Intersection using filter() and save it to 'lst3'. Now find elements either not in lst1 or in lst2, and save them to 'temp'. Finally, append 'temp' to 'lst3'.

What is Unnest in Python?

If some of the elements in the series object have lists, then we can unnest those list elements into multiple rows of the series object. Unnesting is nothing but exploding the lists into rows. So this transformation can be done easily with the help of the pandas series.

How do I make a list in one list in Python?

Use the sum() function to concatenate nested lists to a single list by passing an empty list as a second argument to it.


1 Answers

Clearly a case for a recursive function, but getting the return values to unlist properly is tricky. Here's a function that will do it; it doesn't get the names quite right but that's 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)))
  }
}

Output from unnest(l) is

$all
 [1]  1  2  3  4  5  6  7  8  9 10

$A.all
[1] 1 2

$A.a
[1] 1

$A.b
[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

$B.e
[1]  9 10

and can be massaged into your desired output with

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

To not recurse when there's only one element, 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)))
  }
}
like image 136
Aaron left Stack Overflow Avatar answered Oct 22 '22 03:10

Aaron left Stack Overflow