【问题标题】:Accessing grouping variables in purrr::map() with nested dataframes使用嵌套数据框访问 purrr::map() 中的分组变量
【发布时间】:2019-05-20 05:18:03
【问题描述】:

我将tidyr::nest()purrr::map() (-family) 结合使用,将data.frame 分组,然后对每个子集做一些花哨的事情。考虑以下示例,请忽略我不需要 nest()map() 来执行此操作(这是一个过于简单的示例):

library(dplyr)
library(purrr)
library(tidyr)

mtcars %>% 
  group_by(cyl) %>%
  nest() %>%
  mutate(
    wt_mean = map_dbl(data,~mean(.x$wt))
  )

# A tibble: 8 x 4
    cyl  gear data               cly2
  <dbl> <dbl> <list>            <dbl>
1     6     4 <tibble [4 x 9]>      6
2     4     4 <tibble [8 x 9]>      4
3     6     3 <tibble [2 x 9]>      6
4     8     3 <tibble [12 x 9]>     8
5     4     3 <tibble [1 x 9]>      4
6     4     5 <tibble [2 x 9]>      4
7     8     5 <tibble [2 x 9]>      8
8     6     5 <tibble [1 x 9]>      6

通常当我执行此类操作时,我需要访问map() 中的分组变量(在本例中为cyl)。但是这些分组变量显示为长度与嵌套数据帧中的行数相对应的向量,因此并不容易使用。

有没有办法可以运行以下操作?我希望将wt 的平均值除以每组(即行)的柱面数(cyl)。

mtcars %>% 
  group_by(cyl,gear) %>%
  nest() %>%
  mutate(
    wt_mean = map_dbl(data,~mean(.x$wt)/cyl)
  )


Error in mutate_impl(.data, dots) : 
  Evaluation error: Result 1 is not a length 1 atomic vector.

【问题讨论】:

  • 当您使用map 而不是map_dbl 时会得到什么?我通常从裸map 开始进行调试。当map_dbl 的每次迭代都没有产生单个数值时,就会出现该错误

标签: r dplyr tidyr purrr


【解决方案1】:

cyl 排除在map 电话之外:

mtcars %>% 
  group_by(cyl,gear) %>%
  nest() %>%
  mutate(
    wt_mean = map_dbl(data, ~mean(.x$wt)) / cyl
  )

# A tibble: 8 x 4
    cyl  gear data              wt_mean
  <dbl> <dbl> <list>              <dbl>
1     6     4 <tibble [4 x 9]>    0.516
2     4     4 <tibble [8 x 9]>    0.595
3     6     3 <tibble [2 x 9]>    0.556
4     8     3 <tibble [12 x 9]>   0.513
5     4     3 <tibble [1 x 9]>    0.616
6     4     5 <tibble [2 x 9]>    0.457
7     8     5 <tibble [2 x 9]>    0.421
8     6     5 <tibble [1 x 9]>    0.462

map_dblcyl 视为长度为 8 的向量,因为 nest 会从 data.frame 中删除组。在map_* 函数调用中使用cyl(如在OP 的示例中)会产生8 个长度为8 的向量。

其他2种方法:

两者的结果与上述相同,但根据 OP 的规范,将分组变量保留在 map_* 调用中:

nest之后重新分组

mtcars %>% 
  group_by(cyl,gear) %>%
  nest() %>%
  group_by(cyl, gear) %>%
  mutate(wt_mean = map_dbl(data,~mean(.x$wt)/cyl))

map2 用于迭代 cyl

mtcars %>% 
  group_by(cyl,gear) %>%
  nest() %>%
  mutate(wt_mean = map2_dbl(data, cyl,~mean(.x$wt)/ .y))

【讨论】:

  • 嘿 Zack,这实际上在这个最小的例子上工作得很好。您编辑的另外两种方法(使用group_by() 重新组合和使用map2_*/pmap_*)实际上在其他各种情况下更方便。您介意在您的答案中重新整合这些方法吗? (我确实声明我需要分组变量 within map()
  • 你做到了!我在最后添加了它们。
  • 谢谢!我很乐意接受这个答案。但我也将此提交为an issue on github
【解决方案2】:

dplyr0-8-0 的新版本中,您现在可以使用group_map,我发现它非常适合这个用例。这是the example github用户@yutannihilation

library(dplyr, warn.conflicts = FALSE)

mtcars %>% 
  group_by(cyl) %>%
  group_map(function(data, group_info) {
    tibble::tibble(wt_mean = mean(data$wt) / group_info$cyl)
  })

【讨论】:

    猜你喜欢
    • 2020-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 2017-05-05
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    相关资源
    最近更新 更多