R:合并两个数据帧列表列表
R: merge two lists of lists of dataframes
我有两个这样的数据帧列表列表:
L1 <- list(Q1=list(A=data.frame(X1=1:3),C=data.frame(X1=1:3)),
Q2=list(B=data.frame(X1=1:3),C=data.frame(X1=1:3)))
L2 <- list(Q1=list(B=data.frame(X1=4:6),C=data.frame(X1=4:6)),
Q2=list(A=data.frame(X1=4:6),C=data.frame(X1=4:6)))
第一层的名字 "Q1" 和 "Q2" 在两个列表中是相同的。
我想合并两个列表,这样具有相同名称的数据帧(例如“$Q1$C”)将像 rbind
一样合并,并且新的数据帧将被添加到列表中。所需的输出应如下所示:
> L3
$Q1
$Q1$A
X1
1 1
2 2
3 3
$Q1$B
X1
1 4
2 5
3 6
$Q1$C
X1
1 1
2 2
3 3
4 4
5 5
6 6
$Q2
$Q2$A
X1
1 4
2 5
3 6
$Q2$B
X1
1 1
2 2
3 3
$Q2$C
X1
1 1
2 2
3 3
4 4
5 5
6 6
我尝试了一些使用 Map()
和 lapply()
的组合,但我无法修复它。例如:
L3 <- Map('rbind',lapply(L1,'['),lapply(L2,'['))
感谢任何帮助!
这是一种使用 reshape2::melt
的方法。
library(reshape2);
# Collapse lists and turn into long dataframe
df.long <- rbind.data.frame(
melt(L1, id.vars = "X1"),
melt(L2, id.vars = "X1"));
# Split dataframe into nested list
lst <- lapply(split(df.long, df.long$L1), function(x) split(x, x$L2));
lst <- lapply(lst, function(x) lapply(x, function(y) data.frame(X1 = y$X1)));
str(lst);
#List of 2
# $ Q1:List of 3
# ..$ A:'data.frame': 3 obs. of 1 variable:
# .. ..$ X1: int [1:3] 1 2 3
# ..$ B:'data.frame': 3 obs. of 1 variable:
# .. ..$ X1: int [1:3] 4 5 6
# ..$ C:'data.frame': 6 obs. of 1 variable:
# .. ..$ X1: int [1:6] 1 2 3 4 5 6
# $ Q2:List of 3
# ..$ A:'data.frame': 3 obs. of 1 variable:
# .. ..$ X1: int [1:3] 4 5 6
# ..$ B:'data.frame': 3 obs. of 1 variable:
# .. ..$ X1: int [1:3] 1 2 3
# ..$ C:'data.frame': 6 obs. of 1 variable:
# .. ..$ X1: int [1:6] 1 2 3 4 5 6
数据
L1 <- list(Q1=list(A=data.frame(X1=1:3),C=data.frame(X1=1:3)),
Q2=list(B=data.frame(X1=1:3),C=data.frame(X1=1:3)))
L2 <- list(Q1=list(B=data.frame(X1=4:6),C=data.frame(X1=4:6)),
Q2=list(A=data.frame(X1=4:6),C=data.frame(X1=4:6)))
这是一个使用 base R 的解决方案:
x <- c(L1, L2)
lapply(split(x, names(x)), function(i){
xsub <- do.call(c, unname(i))
lapply(split(xsub, names(xsub)), function(j) do.call(rbind, unname(j)))
})
split(x, names(x))
会把Q1
和Q2
放在一起;
xsub <- do.call(c, unname(i))
会将 Q1
或 Q2
组合成一个列表 data.frames
;
split(xsub, names(xsub))
将 data.frame
按他们的名字分组 (A
, B
, C
);
输出为:
# $Q1
# $Q1$A
# X1
# 1 1
# 2 2
# 3 3
#
# $Q1$B
# X1
# 1 4
# 2 5
# 3 6
#
# $Q1$C
# X1
# 1 1
# 2 2
# 3 3
# 4 4
# 5 5
# 6 6
#
#
# $Q2
# $Q2$A
# X1
# 1 4
# 2 5
# 3 6
#
# $Q2$B
# X1
# 1 1
# 2 2
# 3 3
#
# $Q2$C
# X1
# 1 1
# 2 2
# 3 3
# 4 4
# 5 5
# 6 6
使用 purrr:
library(tidyverse)
f <- function(x) {
map_df(map(x, bind_rows, .id = "id1"), bind_rows, .id = "id2")
}
list(L1, L2) %>%
map_df(f) %>%
split(list(.$id1, .$id2)) %>%
map(select, X1)
我有两个这样的数据帧列表列表:
L1 <- list(Q1=list(A=data.frame(X1=1:3),C=data.frame(X1=1:3)),
Q2=list(B=data.frame(X1=1:3),C=data.frame(X1=1:3)))
L2 <- list(Q1=list(B=data.frame(X1=4:6),C=data.frame(X1=4:6)),
Q2=list(A=data.frame(X1=4:6),C=data.frame(X1=4:6)))
第一层的名字 "Q1" 和 "Q2" 在两个列表中是相同的。
我想合并两个列表,这样具有相同名称的数据帧(例如“$Q1$C”)将像 rbind
一样合并,并且新的数据帧将被添加到列表中。所需的输出应如下所示:
> L3
$Q1
$Q1$A
X1
1 1
2 2
3 3
$Q1$B
X1
1 4
2 5
3 6
$Q1$C
X1
1 1
2 2
3 3
4 4
5 5
6 6
$Q2
$Q2$A
X1
1 4
2 5
3 6
$Q2$B
X1
1 1
2 2
3 3
$Q2$C
X1
1 1
2 2
3 3
4 4
5 5
6 6
我尝试了一些使用 Map()
和 lapply()
的组合,但我无法修复它。例如:
L3 <- Map('rbind',lapply(L1,'['),lapply(L2,'['))
感谢任何帮助!
这是一种使用 reshape2::melt
的方法。
library(reshape2);
# Collapse lists and turn into long dataframe
df.long <- rbind.data.frame(
melt(L1, id.vars = "X1"),
melt(L2, id.vars = "X1"));
# Split dataframe into nested list
lst <- lapply(split(df.long, df.long$L1), function(x) split(x, x$L2));
lst <- lapply(lst, function(x) lapply(x, function(y) data.frame(X1 = y$X1)));
str(lst);
#List of 2
# $ Q1:List of 3
# ..$ A:'data.frame': 3 obs. of 1 variable:
# .. ..$ X1: int [1:3] 1 2 3
# ..$ B:'data.frame': 3 obs. of 1 variable:
# .. ..$ X1: int [1:3] 4 5 6
# ..$ C:'data.frame': 6 obs. of 1 variable:
# .. ..$ X1: int [1:6] 1 2 3 4 5 6
# $ Q2:List of 3
# ..$ A:'data.frame': 3 obs. of 1 variable:
# .. ..$ X1: int [1:3] 4 5 6
# ..$ B:'data.frame': 3 obs. of 1 variable:
# .. ..$ X1: int [1:3] 1 2 3
# ..$ C:'data.frame': 6 obs. of 1 variable:
# .. ..$ X1: int [1:6] 1 2 3 4 5 6
数据
L1 <- list(Q1=list(A=data.frame(X1=1:3),C=data.frame(X1=1:3)),
Q2=list(B=data.frame(X1=1:3),C=data.frame(X1=1:3)))
L2 <- list(Q1=list(B=data.frame(X1=4:6),C=data.frame(X1=4:6)),
Q2=list(A=data.frame(X1=4:6),C=data.frame(X1=4:6)))
这是一个使用 base R 的解决方案:
x <- c(L1, L2)
lapply(split(x, names(x)), function(i){
xsub <- do.call(c, unname(i))
lapply(split(xsub, names(xsub)), function(j) do.call(rbind, unname(j)))
})
split(x, names(x))
会把Q1
和Q2
放在一起;xsub <- do.call(c, unname(i))
会将Q1
或Q2
组合成一个列表data.frames
;split(xsub, names(xsub))
将data.frame
按他们的名字分组 (A
,B
,C
);
输出为:
# $Q1
# $Q1$A
# X1
# 1 1
# 2 2
# 3 3
#
# $Q1$B
# X1
# 1 4
# 2 5
# 3 6
#
# $Q1$C
# X1
# 1 1
# 2 2
# 3 3
# 4 4
# 5 5
# 6 6
#
#
# $Q2
# $Q2$A
# X1
# 1 4
# 2 5
# 3 6
#
# $Q2$B
# X1
# 1 1
# 2 2
# 3 3
#
# $Q2$C
# X1
# 1 1
# 2 2
# 3 3
# 4 4
# 5 5
# 6 6
使用 purrr:
library(tidyverse)
f <- function(x) {
map_df(map(x, bind_rows, .id = "id1"), bind_rows, .id = "id2")
}
list(L1, L2) %>%
map_df(f) %>%
split(list(.$id1, .$id2)) %>%
map(select, X1)