【问题标题】:Implementing map() on a column of nested data frames在一列嵌套数据框上实现 map()
【发布时间】:2017-09-19 19:50:10
【问题描述】:

我正在自学 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)))

【问题讨论】:

    标签: r dplyr tidyverse magrittr purrr


    【解决方案1】:

    因为您在 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
    

    【讨论】:

    • 你是指github.com/tidyverse/tidyverse的开发版本吗?我刚刚重新安装了它(版本 1.1.1.9000),它找不到.data。我得到Error in mutate_impl(.data, dots) : object '.data' not found
    • 开发 dplyr,您可以从 here 安装它。
    猜你喜欢
    • 2017-05-05
    • 1970-01-01
    • 2020-01-22
    • 2018-02-03
    • 2022-08-15
    • 2018-03-21
    • 1970-01-01
    • 2018-03-06
    • 2020-05-21
    相关资源
    最近更新 更多