[英]How to bind rows of dataframes in separate elements within a list of lists
Let's suppose I have a list of lists as follows: 假设我有一个列表列表,如下所示:
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)))
where each list element (1, 2 and 3) is a list which contains two data.frames. 其中每个列表元素(1、2和3)是一个包含两个data.frames的列表。
How can I sequentially bind the rows of the first data.frame
within each (sub)list? 如何依次绑定每个(子)列表中第一个
data.frame
的行? ie lst_1[[1]][[1]]
+ lst_1[[2]][[1]]
+ lst_1[[3]][[1]]
, and eventually do the same for the second data.frame
? 即
lst_1[[1]][[1]]
+ lst_1[[2]][[1]]
+ lst_1[[3]][[1]]
,最后对第二个data.frame
做同样的data.frame
?
Here is my desired output, which is achieved manually with a for loop, however my real list of lists is much larger: 这是我想要的输出,这是通过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]])
}
If I'm interpreting correctly, the base R solution should be pretty straight forward. 如果我的解释正确,那么基本的R解决方案应该很简单。
Map
the rbind
function over each part of the 3 inputs in lst_1
: 将
rbind
函数Map
到lst_1
3个输入的每个部分上:
do.call(Map, c(rbind, lst_1))
This is a slightly obscured way of calling the expanded Map
line of: 这是调用扩展的
Map
行的一种稍微模糊的方法:
Map(rbind, lst_1[[1]], lst_1[[2]], lst_1[[3]])
Which starts to look a lot like your original for
loop, and gives the same result as doing it via do.call
: 它开始看起来很像您的原始
for
循环,并提供与通过do.call
进行操作相同的结果:
identical(
do.call(Map, c(rbind, lst_1)),
Map(rbind, lst_1[[1]], lst_1[[2]], lst_1[[3]])
)
#[1] TRUE
Checks out with the intended result too: 也检查出预期的结果:
identical(lst_out, do.call(Map, c(rbind, lst_1)))
#[1] TRUE
I think the simplest way is to simply purrr::transpose
the list, so that instead of three sublists with two dataframe elements, you have two sublists with three dataframe elements. 我认为最简单的方法是简单地
purrr::transpose
列表,这样就不用三个带有两个dataframe元素的子列表,而是两个带有三个dataframe元素的子列表。 This means that the dataframes to bind are all in the same sublist, so iteration is much simpler and we can map
over the main list. 这意味着要绑定的数据帧都在同一个子列表中,因此迭代要简单得多,我们可以
map
到主列表上。 See below, noting that you can just load purrr
as dplyr::bind_rows
is just a bit faster and tibble::glimpse
is for printing only. 见下文,并指出,你可以加载
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 ...
Created on 2019-04-20 by the reprex package (v0.2.1) 由reprex软件包 (v0.2.1)创建于2019-04-20
Base R solution 基础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))
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.