将自定义函数与 tidyverse 结合使用

M_M*_*M_M 2 r function dplyr tidyverse

我创建了一个虚拟函数来获取一个变量的滞后,我想将它与其他tidyverse函数一起使用。它在我调用后起作用mutate,但在调用后不起作用group_by。它抛出以下错误: Error in mutate_impl(.data, dots) : Not compatible with STRSXP: [type=NULL].

这是一个代表:

#create a function to lag a selected variable
lag_func <- function(df, x) {
  mutate(df, lag = lag(df[,x])) 
}

#works
iris %>% 
  mutate(lead = lead(Petal.Length)) %>%
  lag_func('Petal.Length')

#doesn't work
iris %>%
  group_by(Species) %>%
  mutate(lead = lead(Petal.Length)) %>%
  lag_func('Petal.Length')
Run Code Online (Sandbox Code Playgroud)

知道错误意味着什么和/或如何修复它吗?

小智 5

将列名作为参数传递给tidyverse函数的最佳方法是将其转换为quosureusing enquo()。看这段代码:

lag_func <- function(df, x) {
  x <- enquo(x)
  mutate(df, lag = lag(!!x)) # !! is to evaluate rather than quoting (x)
}
Run Code Online (Sandbox Code Playgroud)

现在让我们尝试一下我们的函数:

iris %>%
  group_by(Species) %>%
  mutate(lead = lead(Petal.Length)) %>%
  lag_func(Petal.Length)

# A tibble: 150 x 7
# Groups:   Species [3]
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species  lead   lag
          <dbl>       <dbl>        <dbl>       <dbl> <fct>   <dbl> <dbl>
 1          5.1         3.5          1.4         0.2 setosa    1.4  NA  
 2          4.9         3            1.4         0.2 setosa    1.3   1.4
 3          4.7         3.2          1.3         0.2 setosa    1.5   1.4
 4          4.6         3.1          1.5         0.2 setosa    1.4   1.3
 5          5           3.6          1.4         0.2 setosa    1.7   1.5
 6          5.4         3.9          1.7         0.4 setosa    1.4   1.4
 7          4.6         3.4          1.4         0.3 setosa    1.5   1.7
 8          5           3.4          1.5         0.2 setosa    1.4   1.4
 9          4.4         2.9          1.4         0.2 setosa    1.5   1.5
10          4.9         3.1          1.5         0.1 setosa    1.5   1.4
# ... with 140 more rows
Run Code Online (Sandbox Code Playgroud)

有关如何tidyverse在自定义函数中使用函数的更多信息,请参阅此处