Использование собственной функции case_when внутри вызова mutate в проблемах с dplyr - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть этот фрейм данных

library(tidyverse)
df <- structure(list(D1_step1 = c("FT", "FF", "FF", "TTT", "FFF", "FFF", 
      "FF", "FFF", "FT", "TT"), barrido = c("B1_B4", "B1_B2", "B1_B4", 
      "B1_B2_B4", "B1_B2_B4", "B1_B2_B4", "B1_B4", "B1_B2_B4", "B1_B4", 
      "B1_B4")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
      -10L))

И эта функция

f1 <- function(sero, barrido){
  as.logical(case_when(str_detect(barrido, "B1") ~ str_sub(sero, 1, 1)))
}

df %>%
mutate(new_col = f1(D1_step1, barrido))

Я делаю это, и она отлично работает. Мне не нужен аргумент barrido в функции, так как он не меняется, и у данных всегда есть столбец с именем 'barrido'. Таким образом, я хотел бы сделать это ....

f2 <- function(sero){
  as.logical(case_when(str_detect(barrido, "B1") ~ str_sub(sero, 1, 1)))
}

df %>%
mutate(new_col = f2(D1_step1))

 Error in stri_detect_regex(string, pattern, negate = negate, opts_regex = opts(pattern)) : 
  object 'barrido' not found

, но компьютер говорит "нет", поэтому я попытался установить аргумент в качестве значения по умолчанию, и я получил другой тип "нет". Nb только что отредактировал это, поскольку я изначально не устанавливал аргумент по умолчанию

f3 <- function(sero, barrido = barrido){
  as.logical(case_when(str_detect(barrido, "B1") ~ str_sub(sero, 1, 1)))
}

df %>%
mutate(new_col = f3(D1_step1))

 Error in stri_detect_regex(string, pattern, negate = negate, opts_regex = opts(pattern)) : 
  promise already under evaluation: recursive default argument reference or earlier problems?

Написание пользовательской функции case_when для использования в dplyr mutate с использованием tidyeval . Этот вопрос не помогает, так как я не хочу писать функцию в качестве case_when в mutate. Комментарии ниже дают представление о том, почему это не работает, и наводят меня на мысль, что может быть решение с использованием tidyeval. Также мне любопытно, что стоит за разницей между сообщениями об ошибках между f2 и f3.

1 Ответ

1 голос
/ 28 февраля 2020

С версией разработки dplyr (которая будет выпущена как dplyr 1.0) вы можете просмотреть текущие столбцы с помощью across().

f2 <- function(sero){
  barrido <- across(all_of("barrido"))[[1]]
  as.logical(case_when(
    str_detect(barrido, "B1") ~ str_sub(sero, 1, 1)
  ))
}

Должно быть четко задокументировано, что эта функция работает только внутри dplyr с фреймами данных, содержащими столбец barrido.

...