如何将数据框行绑定到列表列表中的单独元素中

How to bind rows of dataframes in separate elements within a list of lists

假设我有如下列表:

set.seed(111)
lst_1 = rep(list(list()), 3) 

lst_1[[1]] = list(data.frame(rnorm(5)), data.frame(rnorm(5)))
lst_1[[2]] = list(data.frame(rnorm(5)), data.frame(rnorm(5)))
lst_1[[3]] = list(data.frame(rnorm(5)), data.frame(rnorm(5)))

其中每个列表元素(1、2 和 3)是一个包含两个 data.frames.

的列表

如何在每个(子)列表中顺序绑定第一个 data.frame 的行?即 lst_1[[1]][[1]] + lst_1[[2]][[1]] + lst_1[[3]][[1]],并最终对第二个 data.frame?

做同样的事情

这是我想要的输出,它是通过 for 循环手动实现的,但是我的真实列表列表要大得多:

lst_out = rep(list(list()), 2) 

for (i in 1:2) {
lst_out[[i]] = rbind(lst_1[[1]][[i]], lst_1[[2]][[i]], lst_1[[3]][[i]])
}

我认为最简单的方法是简单地 purrr::transpose 列表,这样您就有两个子列表和三个数据框元素,而不是三个子列表和两个数据框元素。这意味着要绑定的数据帧都在同一个子列表中,因此迭代要简单得多,我们可以 map 遍历主列表。请参阅下文,注意您可以只加载 purrr,因为 dplyr::bind_rows 只是快一点,而 tibble::glimpse 仅用于打印。

library(tidyverse)
set.seed(111)
lst_1 = rep(list(list()), 3) 

lst_1[[1]] = list(data.frame(rnorm(5)), data.frame(rnorm(5)))
lst_1[[2]] = list(data.frame(rnorm(5)), data.frame(rnorm(5)))
lst_1[[3]] = list(data.frame(rnorm(5)), data.frame(rnorm(5)))

lst_1 %>%
  transpose %>%
  map(bind_rows) %>%
  glimpse
#> List of 2
#>  $ :'data.frame':    15 obs. of  1 variable:
#>   ..$ rnorm.5.: num [1:15] 0.235 -0.331 -0.312 -2.302 -0.171 ...
#>  $ :'data.frame':    15 obs. of  1 variable:
#>   ..$ rnorm.5.: num [1:15] 0.14 -1.497 -1.01 -0.948 -0.494 ...

reprex package (v0.2.1)

于 2019-04-20 创建

基础 R 解决方案

set.seed(111)
lst_1 <- rep(list(list()), 3) 

lst_1[[1]] <- list(data.frame(rnorm(5)), data.frame(rnorm(5)))
lst_1[[2]] <- list(data.frame(rnorm(5)), data.frame(rnorm(5)))
lst_1[[3]] <- list(data.frame(rnorm(5)), data.frame(rnorm(5)))

lst_out_2 <- list()

for (i in 1:2) { 
  lst_out_2[[i]] <- do.call('rbind', sapply(lst_1, `[`, i))
}

如果我的解释正确,基本的 R 解决方案应该非常简单。 Map rbind 函数作用于 lst_1 中 3 个输入的每个部分:

do.call(Map, c(rbind, lst_1))

这是调用扩展的 Map 行的一种稍微模糊的方式:

Map(rbind, lst_1[[1]], lst_1[[2]], lst_1[[3]])

开始看起来很像原来的 for 循环,并给出与通过 do.call:

相同的结果
identical(
  do.call(Map, c(rbind, lst_1)),
  Map(rbind, lst_1[[1]], lst_1[[2]], lst_1[[3]])
)
#[1] TRUE

也检查了预期的结果:

identical(lst_out, do.call(Map, c(rbind, lst_1)))
#[1] TRUE