我们说我有一个列表结构,其中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
我想找到一种方法来分别从父列表元素(D
,E
)中合并data.frames
和A
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]]))
}
答案 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))
也可以使用purrr
和dplyr
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)))