使用dplyr,purrr将列表列表中的每个ith元素组合在一起 [英] Combine every ith element of a list of lists together using dplyr, purrr
问题描述
我有一个结构相同的列表,如下所示:
I have a list of identically structured lists as follows:
test1 <- list(first = data.frame(col1 = c(1,2), col2 = c(3,4)),
second = data.frame(COL1 = c(100,200), COL2 = c(300, 400)))
test2 <- list(first = data.frame(col1 = c(5,6), col2 = c(7,8)),
second = data.frame(COL1 = c(500,600), COL2 = c(700,800)))
orig.list <- list(test1, test2)
我要:
- 将每个嵌套列表的第一个元素的行绑定在一起,将行绑定每个嵌套列表的第二个元素都在一起,等等。
- 将结果元素重组为一个列表,其结构与第一个列表相同。
我可以轻松地通过以下方式逐个元素进行操作:
I can easily do this element by element via:
firsts <- orig.list %>% purr::map(1) %>% dplyr::bind_rows()
seconds <- orig.list %>% purr::map(2) %>% dplyr::bind_rows()
new.list <- list(first = firsts, second = seconds)
但是,对于n个列表元素,这要求我:
However, for n list elements this requires that I:
- 知道元素数在每个列表中,
- 知道元素的名称和顺序,以便我可以使用正确的名称和顺序重新创建新列表,
- 复制并
我正在寻找如何应用purrr:map(或其他一些tidyverse)函数)来组合列表列表的所有元素,并保留元素名称和顺序。
I'm looking for how to apply purrr:map (or some other tidyverse function) more generically to combine all elements of a list of lists, preserving the element names and order.
推荐答案
在显示数据的最简单情况下,可以使用 pmap
可以并行浏览列表,而 bind_rows
可以组合单个数据帧:
Under the simplest cases as you've shown with your data, you can use pmap
to walk through the list in parallel and bind_rows
to combine individual data frames:
library(tidyverse)
pmap(orig.list, bind_rows)
#$first
# col1 col2
#1 1 3
#2 2 4
#3 5 7
#4 6 8
#$second
# COL1 COL2
#1 100 300
#2 200 400
#3 500 700
#4 600 800
identical(pmap(orig.list, bind_rows), new.list)
# [1] TRUE
稍微说一下通用一些,即处理每个子列表中元素的数量和名称顺序可能不同的情况,您可以使用:
To make this a little bit more generic, i.e. handles cases where the number of elements and order of names in each sublist can vary, you can use:
map(map_df(orig.list, ~ as.data.frame(map(.x, ~ unname(nest(.))))), bind_rows)
即您将每个子列表嵌套为一个数据框,然后让 bind_rows
检查您的名字。
i.e. you nest each sub list as a data frame, and let bind_rows
to check the names for you.
测试用例:
与 test1
相同,切换<$中元素的顺序c $ c> test2 :
test2 <- list(second = data.frame(COL1 = c(500,600), COL2 = c(700,800)),
first = data.frame(col1 = c(5,6), col2 = c(7,8)))
orig.list1 <- list(test1, test2)
map(map_df(orig.list1, ~ as.data.frame(map(.x, ~ unname(nest(.))))), bind_rows)
给出:
#$first
# col1 col2
#1 1 3
#2 2 4
#3 5 7
#4 6 8
#$second
# COL1 COL2
#1 100 300
#2 200 400
#3 500 700
#4 600 800
现在从 test2 中删除一个元素:
Now drop one element from test2:
test2 <- list(first = data.frame(col1 = c(5,6), col2 = c(7,8)))
orig.list2 <- list(test1, test2)
map(map_df(orig.list2, ~ as.data.frame(map(.x, ~ unname(nest(.))))), bind_rows)
给出:
#$first
# col1 col2
#1 1 3
#2 2 4
#3 5 7
#4 6 8
#$second
# COL1 COL2
#1 100 300
#2 200 400
这篇关于使用dplyr,purrr将列表列表中的每个ith元素组合在一起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!