我正在教自己R tidyverse purr()
包,并且在嵌套数据框列上实现map()
时遇到问题。有人可以解释我错过了什么吗?
使用基础R ChickWeight数据集作为示例,如果我第一次过滤饮食#1,我可以轻松获得饮食#1下每个时间点的观察次数:
library(tidyverse)
ChickWeight %>%
filter(Diet == 1) %>%
group_by(Time) %>%
summarise(counts = n_distinct(Chick))
这很棒,但我想立刻为每种饮食做这件事,我认为嵌套数据并用map()
迭代它将是一个很好的方法。
这就是我所做的:
example <- ChickWeight %>%
nest(-Diet)
实现这个地图功能,然后实现我的目标:
map(example$data, ~ .x %>% group_by(Time) %>% summarise(counts = n_distinct(Chick)))
但是,当我尝试使用管道将相同的命令放入原始数据框的另一列时,它会失败。
example %>%
mutate(counts = map(data, ~ .x %>% group_by(Time) %>% summarise(counts = n_distinct(Chick))))
Error in eval(substitute(expr), envir, enclos) :
variable 'Chick' not found
为什么会这样?
我也尝试将数据框拆分成一个列表但它不起作用。
ChickWeight %>%
split(.$Diet) %>%
map(data, ~ .x %>% group_by(Time) %>% summarise(counts = n_distinct(Chick)))
答案 0 :(得分:4)
因为您在dplyr NSE中使用了dplyr非标准评估,所以对于搜索Chick
的环境感到困惑。它可能是一个错误,真的,但可以通过开发版本的新.data
代词来避免它,它指定了要查看的位置:
library(tidyverse)
ChickWeight %>%
nest(-Diet) %>%
mutate(counts = map(data,
~.x %>% group_by(Time) %>%
summarise(counts = n_distinct(.data$Chick))))
#> # A tibble: 4 × 3
#> Diet data counts
#> <fctr> <list> <list>
#> 1 1 <tibble [220 × 3]> <tibble [12 × 2]>
#> 2 2 <tibble [120 × 3]> <tibble [12 × 2]>
#> 3 3 <tibble [120 × 3]> <tibble [12 × 2]>
#> 4 4 <tibble [118 × 3]> <tibble [12 × 2]>
要通过列表管道,将map
的第一个参数留空以传递到要迭代的列表中:
ChickWeight %>%
split(.$Diet) %>%
map(~ .x %>% group_by(Time) %>% summarise(counts = n_distinct(Chick))) %>% .[[1]]
#> # A tibble: 12 × 2
#> Time counts
#> <dbl> <int>
#> 1 0 20
#> 2 2 20
#> 3 4 19
#> 4 6 19
#> 5 8 19
#> 6 10 19
#> 7 12 19
#> 8 14 18
#> 9 16 17
#> 10 18 17
#> 11 20 17
#> 12 21 16
更简单的选择是按两列分组:
ChickWeight %>% group_by(Diet, Time) %>% summarise(counts = n_distinct(Chick))
#> Source: local data frame [48 x 3]
#> Groups: Diet [?]
#>
#> Diet Time counts
#> <fctr> <dbl> <int>
#> 1 1 0 20
#> 2 1 2 20
#> 3 1 4 19
#> 4 1 6 19
#> 5 1 8 19
#> 6 1 10 19
#> 7 1 12 19
#> 8 1 14 18
#> 9 1 16 17
#> 10 1 18 17
#> # ... with 38 more rows