Rat*_*nil 3 r dplyr tidyr purrr
我tidyr::nest()与purrr::map()(-family)结合使用将a 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
Run Code Online (Sandbox Code Playgroud)
通常,当我执行此类操作时,需要访问中的分组变量(cyl在这种情况下)map()。但是这些分组变量显示为向量,其长度与嵌套数据框中的行数相对应,因此不容易使用。
有没有办法可以执行以下操作?我想的平均值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.
Run Code Online (Sandbox Code Playgroud)
以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
Run Code Online (Sandbox Code Playgroud)
map_dbl认为cyl作为因为一个长度为8矢量nest中移除了组从data.frame。cyl在map_*函数调用中使用(例如在OP的示例中)会产生8个长度为8的向量。
两者都具有与上述相同的结果,但map_*根据OP的规范将分组的变量保留在调用中:
nestmtcars %>%
group_by(cyl,gear) %>%
nest() %>%
group_by(cyl, gear) %>%
mutate(wt_mean = map_dbl(data,~mean(.x$wt)/cyl))
Run Code Online (Sandbox Code Playgroud)
map2 遍历 cylmtcars %>%
group_by(cyl,gear) %>%
nest() %>%
mutate(wt_mean = map2_dbl(data, cyl,~mean(.x$wt)/ .y))
Run Code Online (Sandbox Code Playgroud)