Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R: Combining Nested List Elements by Name

Tags:

r

Let's say I have a list structure where there are data.frames nested in each element.

l <- list(A = list(D = data.frame(V1 = seq(3), V2 = LETTERS[1:3]),
                   E = data.frame(V1 = seq(3), V2 = LETTERS[4:6])),
          B = list(D = data.frame(V1 = seq(3), V2 = LETTERS[7:9]),
                   E = data.frame(V1 = seq(3), V2 = LETTERS[10:12])))

$A
$A$D
  V1 V2
1  1  A
2  2  B
3  3  C

$A$E
  V1 V2
1  1  D
2  2  E
3  3  F


$B
$B$D
  V1 V2
1  1  G
2  2  H
3  3  I

$B$E
  V1 V2
1  1  J
2  2  K
3  3  L

I would like to find a way to combine the D and E data.frames respectively from the parent list elements (A,B) so the output would be like this:

$D
  V1 V2
1  1  A
2  2  B
3  3  C
4  1  G
5  2  H
6  3  I

$E
  V1 V2
1  1  D
2  2  E
3  3  F
4  1  J
5  2  K
6  3  L

I can accomplish this with a loop but I am trying to find something a little more efficient/elegant.

out <- vector("list", length(list))
for(i in c("D","E")){
  out[[i]] <- do.call("rbind", lapply(l, function(x) x[[i]]))
}
like image 809
cdeterman Avatar asked Oct 28 '15 15:10

cdeterman


1 Answers

I would use a more elegant approach with data.table (not necessarily more efficient):

library(data.table)

lapply(c('E','D'), function(u) rbindlist(lapply(l, `[[`, u)))
#$A
#   V1 V2
#1:  1  D
#2:  2  E
#3:  3  F
#4:  1  J
#5:  2  K
#6:  3  L

#$B
#   V1 V2
#1:  1  A
#2:  2  B
#3:  3  C
#4:  1  G
#5:  2  H
#6:  3  I

In base R, this can be done with

lapply(c('E','D'), function(u) do.call(rbind, lapply(l, `[[`, u)))
like image 93
Colonel Beauvel Avatar answered Sep 29 '22 14:09

Colonel Beauvel