首页 文章

代码无法使用R中的purrr包中的映射

提问于
浏览
3

我正在学习purrr包中的map函数,并且以下代码不起作用:

library(purrr)
library(dplyr)

df1 = data.frame(type1 = c(rep('a',5),rep('b',5)),
             x = 1:10,
             y = 11:20) 

df1 %>% 
  group_by(type1) %>% 
  nest() %>% 
  map(.$data,with(.x, x + y))

df1 %>% 
  group_by(type1) %>% 
  nest() %>% 
  map(.$data,function(df) df$x + df$y)

对于最后两个代码块,错误返回为:

错误:索引1的长度必须为1

相反,以下两个代码块运行良好,

df1 %>% 
  group_by(type1) %>% 
  nest() %>% .$data %>% 
  map(.,~with(.x, .x$x + .x$y))


df1 %>% 
  group_by(type1) %>% 
  nest() %>% .$data %>% 
  map(.,~with(.x, .x$x + .x$y))

任何人都可以帮助我理解错误以及如何解决它们?

2 回答

  • 6

    您需要在 map 表达式周围添加大括号,因为 . 在函数中不会显示为单独的参数占位符,因此magrittr管道正在应用第一个参数规则,您可以阅读更多有关here的内容 . 并使用 ~ 来构造一个 map 所期望的函数:

    df1 %>% 
        group_by(type1) %>% 
        nest() %>% 
        { map(.$data, ~ with(.x, x + y)) }
    
    #[[1]]
    #[1] 12 14 16 18 20
    
    #[[2]]
    #[1] 22 24 26 28 30
    

    类似地,第二种方法:

    df1 %>% 
        group_by(type1) %>% 
        nest() %>% 
        { map(.$data,function(df) df$x + df$y) }
    #[[1]]
    #[1] 12 14 16 18 20
    
    #[[2]]
    #[1] 22 24 26 28 30
    
  • 2

    如果你想使用 split() ,我通常会分割我的分组因子,然后只为我想要为新创建的列表中的单个tibble / dataframe做一个匿名函数:

    df1 %>% 
        split(.$type1) %>% 
        map(~ mutate(., z = x + y) %>% # chain like you would a single tib
            select(z) %>%
            unlist(T,F))
    $a
    [1] 12 14 16 18 20
    
    $b
    [1] 22 24 26 28 30
    

相关问题