我有两个数据帧的列表
a = list(
mtcars %>% as_tibble() %>% select(-vs),
mtcars %>% as_tibble() %>% sample_n(17)
)
并在数据集中添加新列
b = a %>%
map(~ mutate(.x, class = floor(runif(nrow(.x), 0, 2)))) %>%
map(~ nest(.x, -class))
现在,我想基于class
将两个列表元素合并为一个小标题。具体来说,我正在寻找一种比inner_join(pluck(b, 1), pluck(b, 2), "class")
更“平滑”的解决方案,该解决方案可以提供理想的结果,但是如果列表a
中涉及更多的数据集,则会很快变得混乱。
答案 0 :(得分:1)
这个问题还不是很清楚,但是似乎有足够的用例可以解决这个问题。我向a
添加了一些其他数据帧,它们的结构类似,因为您使用的样本太小,无法真正看到需要处理的内容。
library(tidyverse)
set.seed(123)
a <- list(
mtcars %>% as_tibble() %>% select(-vs),
mtcars %>% as_tibble() %>% sample_n(17),
mtcars %>% as_tibble() %>% slice(1:10),
mtcars %>% as_tibble() %>% select(mpg, cyl, disp)
)
# same construction of b as in the question
您可以使用purrr::reduce
重复执行inner_join
调用,返回嵌套数据帧的单个数据帧。这很简单,但是我想不出一种为联接提供suffix
参数的好方法,该参数默认分配.x
和.y
来区分重复的列名。所以你得到了这些奇怪的名字:
b %>%
reduce(inner_join, by = "class")
#> # A tibble: 2 x 5
#> class data.x data.y data.x.x data.y.y
#> <dbl> <list> <list> <list> <list>
#> 1 1 <tibble [11 × 10… <tibble [8 × 11… <tibble [3 × 11… <tibble [17 × …
#> 2 0 <tibble [21 × 10… <tibble [9 × 11… <tibble [7 × 11… <tibble [15 × …
您可能可以通过在data1
之前创建data2
,reduce
之类的名称来处理名称,但是我决定最快的方法是仅用索引替换后缀列表b
中每个数据帧的大小。一个更复杂的命名方案将是另一个问题的任务。
b %>%
reduce(inner_join, by = "class") %>%
rename_at(vars(starts_with("data")),
str_replace, "(\\.\\w)+$", as.character(1:length(b))) %>%
names()
#> [1] "class" "data1" "data2" "data3" "data4"