我有一个结构相同的列表清单如下:
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)
我想:
我可以通过以下方式轻松地按元素执行此元素:
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个列表元素,这需要I:
我正在寻找如何更普遍地应用purrr:map(或其他一些tidyverse函数)来组合列表列表的所有元素,保留元素名称和顺序。
答案 0 :(得分:1)
在您显示数据的最简单情况下,您可以使用pmap
并行浏览列表,bind_rows
组合各个数据框:
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
为了使这一点更通用,即处理每个子列表中元素数量和名称顺序可能不同的情况,您可以使用:
map(map_df(orig.list, ~ as.data.frame(map(.x, ~ unname(nest(.))))), bind_rows)
即。将每个子列表嵌套为数据框,让bind_rows
为您检查名称。
测试用例:
如果test1
相同,请切换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 中删除一个元素:
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
答案 1 :(得分:1)
您想要purrr::transpose
:
library(purrr)
library(dplyr)
transpose(orig.list) %>% map(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