从 dplyr::mutate 调用用户定义的函数

Calling user defined functions from dplyr::mutate

我正在从事一个涉及许多不同小标题的项目,所有小标题都有一个格式为 YYYYMM 的 period 变量。下面是我所有小标题的示例:

tibble_1 <- tibble::tibble(
  period = c(201901, 201912, 201902, 201903),
  var_1 = rnorm(4),
  var_2 = rnorm(4)
)

但对于某些操作(即时间序列图),使用实际的日期变量更容易。所以我使用 mutate 将 period 变量转换为日期,如下所示:

tibble_1 %>% 
  dplyr::mutate(
    date = lubridate::ymd(stringr::str_c(period, "01"))
)

因为我会经常这样做,而且日期转换不是我在调用 mutate 时要做的唯一改变,我想要一个 user-defined 函数我可以从 mutate 调用中调用。这是我的函数:

period_to_date <- function() {
  lubridate::ymd(stringr::str_c(period, "01"))
}

我以后会这样称呼它:

tibble_1 %>% 
  dplyr::mutate(
    date = period_to_date()
)

问题是,R 找不到句点 object(它本身并不是真正的 object,而是 tibble 的一部分)。

> Error in stri_c(..., sep = sep, collapse = collapse, ignore_null = 
TRUE) : object 'period' not found 

我很确定我需要定义一个 data-mask 以便执行 period_to_date 的环境可以在它的 parent 环境中查找 object (它应该始终是调用者环境,因为包含 period 列的 tibble 并不总是相同的),但我似乎无法弄清楚该怎么做。

该函数不知道您要修改哪个对象。在函数中传递 period 对象并像这样使用它:

period_to_date <- function(period) {
  lubridate::ymd(stringr::str_c(period, "01"))
  #Can also use
  #as.Date(paste0(period,"01"), "%Y%m%d")
}

tibble_1 %>% 
  dplyr::mutate(date = period_to_date(period))

#  period   var_1  var_2 date      
#   <dbl>   <dbl>  <dbl> <date>    
#1 201901 -0.476  -0.456 2019-01-01
#2 201912 -0.645   1.45  2019-12-01
#3 201902 -0.0939 -0.982 2019-02-01
#4 201903  0.410   0.954 2019-03-01

考虑将列名作为参数传递给您的函数:

library(dplyr)


period_to_date <- function(x) {
  lubridate::ymd(stringr::str_c(x, "01"))
}

df <- data.frame(x = 1:3, period = c('201903', '202001', '201511'))

df %>% mutate(p2 = period_to_date(period))
#>   x period         p2
#> 1 1 201903 2019-03-01
#> 2 2 202001 2020-01-01
#> 3 3 201511 2015-11-01

reprex package (v0.3.0)

于 2020 年 1 月 10 日创建