hammoire
hammoire

Reputation: 361

Using a custom case_when function inside a mutate call in dplyr issues

I have this data frame

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))

AND this function

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))

I do this and it works fine. I don't need the barrido argument in the function as this does not vary and the the data always has a column named 'barrido'. Thus I'd like to do this....

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

but computer says no so I tried setting the argument as a default and I got a different kind of no. Nb just edited this as I hadn't actually set the argument as default originally

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?

Writing a custom case_when function to use in dplyr mutate using tidyeval. This question doesn't help as I don't want to write the function as a case_when within a mutate. The comments below give an indication as to why this not working and lead me to believe that there may be a solution using tidyeval. Also I am curious as to what is behind the difference between the error messages between f2 and f3.

Upvotes: 1

Views: 1249

Answers (1)

Lionel Henry
Lionel Henry

Reputation: 6803

With the development version of dplyr (to be released as dplyr 1.0) you can peek at the current columns with across().

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

It should be clearly documented that this function only works inside dplyr with data frames containing a barrido column.

Upvotes: 1

Related Questions