R:按名称组合嵌套列表元素

时间:2015-10-28 15:24:17

标签: r

我们说我有一个列表结构,其中data.frames嵌套在每个元素中。

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

我想找到一种方法来分别从父列表元素(DE)中合并data.framesA B,以便输出将是这样的:

$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

我可以通过循环实现这一点,但我试图找到更有效/更优雅的东西。

out <- vector("list", length(list))
for(i in c("D","E")){
  out[[i]] <- do.call("rbind", lapply(l, function(x) x[[i]]))
}

3 个答案:

答案 0 :(得分:4)

我们将嵌套list展平为单个list,其中包含4个元素(l1),然后将split'l1'替换为替换后的'l1'名称使用.的前缀部分最多为sub。然后,我们rbind使用list嵌套do.call

l1 <- do.call('c', l)
lapply(split(l1,sub('.*\\.', '', names(l1))),
                      function(x) do.call(rbind, x))

也可以使用purrrdplyr

来完成此操作
library(purrr)
library(dplyr)
transpose(l) %>%
          map(bind_rows)
#$D
#Source: local data frame [6 x 2]

#     V1    V2
#  (int) (chr)
#1     1     A
#2     2     B
#3     3     C
#4     1     G
#5     2     H
#6     3     I

#$E
#Source: local data frame [6 x 2]

#     V1    V2
#  (int) (chr)
#1     1     D
#2     2     E
#3     3     F
#4     1     J
#5     2     K
#6     3     L

答案 1 :(得分:3)

我不知道这是否更有效:

l1 <- unlist(l, recursive = FALSE)
D <- do.call(rbind, l1[grepl("\\.D", names(l1))])
E <- do.call(rbind, l1[grepl("\\.E", names(l1))])

如果重要,您需要随后修改行名称。

答案 2 :(得分:3)

我会使用更优雅的方法使用data.table(不一定更高效):

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

在基础R中,可以使用

完成
lapply(c('E','D'), function(u) do.call(rbind, lapply(l, `[[`, u)))