Вызов пользовательских функций из dplyr :: mutate - PullRequest
2 голосов
/ 11 января 2020

Я работаю над проектом, который включает в себя много разных тибблов, каждый из которых имеет переменную period в формате ГГГГММ. Ниже приведен пример того, как выглядят все мои тиблы:

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

Но для некоторых операций (например, временных рядов) проще работать с реальной переменной Date. Поэтому я использую mutate для преобразования переменной периода в дату следующим образом:

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

Поскольку я буду много заниматься этим, и преобразование даты - не единственная мутация, которую я собираюсь делать при вызове mutate я хотел бы иметь пользовательскую функцию, которую я могу вызвать из вызова mutate. Вот моя функция:

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

Который я бы позже назвал так:

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

Проблема в том, что R не может найти объект периода (который на самом деле не является объектом в сам, но часть тиббла).

Ошибка в stri_ c (..., sep = sep, collapse = collapse, ignore_null = TRUE): объект 'period' не найден

Я почти уверен, что мне нужно определить маску данных, чтобы envir, в котором выполняется period_to_date, мог искать объект в его родительском envir (который всегда должен быть envir вызывающего, так как тиббл, содержащий переменная периода не всегда одинакова), но я не могу понять, как это сделать.

Ответы [ 2 ]

4 голосов
/ 11 января 2020

Функция не знает, какой объект вы хотите изменить. Передайте объект 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
1 голос
/ 11 января 2020

Рассмотрите возможность передачи имени столбца в качестве аргумента вашей функции:

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

Создано в 2020-01-10 пакетом представлением (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...