合并两个数据框列表的列表。

3

我有两个列表,其中包含像这样的数据框的列表:

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,'['))

非常感谢您的帮助!

3个回答

5

以下是一种使用基本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))将合并Q1Q2成一个列表data.frames;
  • split(xsub, names(xsub))将通过它们的名称(A, B, C)将data.frame分组;

输出结果为:

# $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

我也喜欢这个没有使用库的解决方案。谢谢!我一直在想是否有一行代码的解决方案,但是你的方法似乎更加优雅。太棒了! - rosapluesch

0
这是一种使用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)))

0
使用 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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接