Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

pass values through to piped dplyr verb inside if{} statement in function

Say I have this data:

d <- msleep %>% 
      mutate(comfort_color_desk = sample(c(0,1), replace=TRUE, size=nrow(msleep)),
             comfort_color_chair = sample(c(0,1), replace=TRUE, size=nrow(msleep))) 

I want to pass it through to a dplyr chain that lives inside a function i’ve made, which also includes an indicator to trigger an {if} clause inside of the chain.

For example (this works just fine):

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

test_fcn <- function(.x, .y, .count = NULL) {
  .x %>% select(order, .y) %>%
    {if(isTRUE(.count)) count(.,!!ensym(.y)) else .} 
}

d %>% test_fcn(., .y = "comfort_color_desk", .count = TRUE)

This shows the basic principle of what I want to do. The problem i’m facing is when I want to just pass through a part of column name and paste that with a string and evaluate it as a data column inside the function.

For example (this does not work):

test_2_fcn <- function(.x, .y, .z, .compare = NULL) {
  .x %>% 
    {if(isTRUE(.compare)) filter(., paste0("comfort_color_", !!ensym(.y)) == 1 & paste0("comfort_color", !!ensym(.z)) == 1) else .} 
}

d %>% test_2_fcn(., .y = "desk", .z = "chair", .compare = TRUE)

I suspect this is a problem with tidy evaluation. Can anyone point in the right direction here please?

>Solution :

This is an issue of tidy evaluation. paste0 function is being evaluated before the !!ensym() is evaluated, now it is tried to paste the literal string "comfort_color_" with the symbol .y or .z instead of the values.

We could use the sym() function to convert the string to a symbol and then use paste() to concatenate the strings together.

library(dplyr)

test_2_fcn <- function(.x, .y, .z, .compare = NULL) {
  .x %>% 
    {if(isTRUE(.compare)) filter(., !!sym(paste0("comfort_color_", .y)) == 1 & !!sym(paste0("comfort_color_", .z)) == 1) else .} 
}

d %>% test_2_fcn(., .y = "desk", .z = "chair", .compare = TRUE)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading