使用Map函数在R语言中进行深度合并列。

3

我正在尝试将一列绑定到一个列表中的另一个列表,但没有成功。如果列表的深度为1,则示例如下,我希望在每个列表对象的示例数据框中添加日期:

ex_df_plain <- list(cbind(1,2), 
                cbind(3,4))
Map(cbind, as.list(c(2016, 2017)), ex_df_plain)

[[1]]
     [,1] [,2] [,3]
[1,] 2016    1    2

[[2]]
     [,1] [,2] [,3]
[1,] 2017    3    4

但是,当我尝试将此应用于深度大于1的列表对象时,cbind会减少列表元素而不是组合它们:

at_depth_df <- list(as.list(c(1,2)), as.list(c(3,4)))

Map(cbind, 
    list(as.list(c(2015, 2016)), as.list(c(2017, 2018))),
    at_depth_df)

[[1]]
     [,1] [,2]
[1,] 2015 1   
[2,] 2016 2   

[[2]]
     [,1] [,2]
[1,] 2017 3   
[2,] 2018 4

我期望的输出应该是

[[1]]
[[1]][[1]]
     [,1] [,2]
[1,] 2015    1

[[1]][[2]]
     [,1] [,2]
[1,] 2016    2


[[2]]
[[2]][[1]]
     [,1] [,2]
[1,] 2017    3

[[2]][[2]]
     [,1] [,2]
[1,] 2018    4
1个回答

2
我们需要一个递归的 Map
Map(function(x, y) Map(cbind, x, y), lst1, at_depth_df)

在哪里

lst1 <- list(as.list(c(2015, 2016)), as.list(c(2017, 2018)))

我们可以编写一个函数来实现这个功能。
f1 <- function(x, y, fun) {
    if(is.atomic(x)  && is.atomic(y)) {
      x1 <- match.fun(fun)(x,y)
      dimnames(x1) <- NULL
      x1
       } else {
         Map(f1, x, y, MoreArgs = list(fun = fun))
    }
}

f1(lst1, at_depth_df, cbind)
#[[1]]
#[[1]][[1]]
#     [,1] [,2]
#[1,] 2015    1

#[[1]][[2]]
#     [,1] [,2]
#[1,] 2016    2


#[[2]]
#[[2]][[1]]
#     [,1] [,2]
#[1,] 2017    3

#[[2]][[2]]
#     [,1] [,2]
#[1,] 2018    4

1
感谢这个函数,这是我见过的最美丽的 R 代码 之一... 在处理 HTML 节点导出时非常有用。 - Hanjo Odendaal

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