Home > OS >  Custom function: Return a tidyselect argument as character-string, without executing the argument
Custom function: Return a tidyselect argument as character-string, without executing the argument

Time:03-04

I would like to create a segment in my custom function where the input of the argument "evars" is returned as a character string, without executing/evaluating the argument. The argument is a tidyselect function used to extract specified columns from a data frame.

The simplified function:

df <- data.frame(var1  = c("value_1", "value_2"),
                 var2.1 = c("value_1", "value_2"),
                 var2.2 = c("value_1", "value_2"),
                 var3 =  c("value_1", "value_2"))

customfunction <- function(df = df, evars = NULL){
   df2 <- df %>% select({{evars}}) 
   if(!is.null(evars)){paste(evars)}
} 

Now i would like it to return the argument as a character string, without executing it:

> customfunction(df = df, evars = c("var1",contains("2")))
[1] "c("var1",contains("2"))"

However, now it will return:

Error: `contains()` must be used within a *selecting* function.
i See <https://tidyselect.r-lib.org/reference/faq-selection-context.html>.
Run `rlang::last_error()` to see where the error occurred.

How can I make the function return the exact input for the argument "evars", without having it executed?

The problem seems to occur due to the tidyselect function contains(), e.g. this code results in no error:

> customfunction(df=df,evars=c("var1","var3"))
[1] "var1" "var3"

CodePudding user response:

We could use match.call() and extract the 'evars'

customfunction <- function(df = df, evars = NULL){
   v1 <- match.call()$evars
   df2 <- df %>%
     select({{evars}}) 
     
     v1
  
   
} 

-testing

customfunction(df = df, evars = c("var1",contains("2")))
c("var1", contains("2"))

If the output needs to be string, then wrap with capture.output

customfunction <- function(df = df, evars = NULL){
   v1 <- capture.output(match.call()$evars)
   df2 <- df %>%
     select({{evars}}) 
     
     v1
  
   
} 

customfunction(df = df, evars = c("var1",contains("2")))
[1] "c(\"var1\", contains(\"2\"))"
  • Related