将清单中的小标题加入一个小标题

时间:2019-05-15 20:06:51

标签: r dplyr tidyverse tidyr purrr

我有两个数据帧的列表

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中涉及更多的数据集,则会很快变得混乱。

1 个答案:

答案 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之前创建data2reduce之类的名称来处理名称,但是我决定最快的方法是仅用索引替换后缀列表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"