如何将数据框行绑定到列表列表中的单独元素中
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
假设我有如下列表:
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