Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function parameter; passing variable name without quotes

Tags:

r

dplyr

The question is similar than this one:

Pass a data.frame column name to a function

I have a function:

optimal_cutpoint <- function(data, ..., choice){
  selection <- dplyr::select(data, ...)
  choice <- data[[choice]]
  # do something with those two objects
}

The function I would use the following way:

choicedata <- data.frame(PTV.A = c(0, 10, 5, 4, 7, 1, 2, 0, 0, 10),
                     PTV.B = c(5, 0, 1, 10, 6, 7, 10, 9, 5, 0),
                     PTV.C = c(10, 5, 10, 5, 2, 8, 0, 5, 5, 0),
                     VOTE = c("C", "A", "C", "B", "B", "C", "B","B", "B", "A"))
optimal_cutpoint(choicedata, PTV.A:PTV.C, choice = "VOTE")

Now to my question. With the ... I can write the variable names without quotes. Is there a possibility that I can write the "VOTE" without the quotes? I would prefere to write it without quotes to be consistent in the function.

If I use dplyr::select it searches for choice instead of vote.

dplyr::select(data,choice)
like image 740
Benjamin Schlegel Avatar asked Dec 04 '18 14:12

Benjamin Schlegel


2 Answers

Add the line marked ##

optimal_cutpoint <- function(data, ..., choice){
  selection <- dplyr::select(data, ...)
  choice <- deparse(substitute(choice)) ##
  choice <- data[[choice]]
  # do something with those two objects
}

out <- optimal_cutpoint(choicedata, PTV.A:PTV.C, choice = VOTE)
out
## [1] C A C B B C B B B A
## Levels: A B C
like image 119
G. Grothendieck Avatar answered Nov 10 '22 10:11

G. Grothendieck


This is exactly what quosures are for, see here for more info. Bonus reference to pull which is basically the dplyr equivalent to [[.

optimal_cutpoint <- function(data, ..., choice){
  choice_quo = enquo(choice)
  selection <- dplyr::select(data, ...)
  choice <-dplyr::pull(data, !!choice_quo)
  # do something with those two objects
}

I'm surprised that things work automagically with unquoted arguments in ..., I never tried that before.

EDIT some extra clarification on quo and enquo, since I made this mistake in my original answer. Use quo if you are using an unquoted value directly, and enquo if you are interpreting the value of an unquoted argument to a function. Compare

data(iris)
myvar = quo(Species)
select(iris, !!myvar)

to

myfun = function(d, myvar) {
  quovar = enquo(myvar)
  select(iris, !!quovar)
}
myfun(iris, Species)
like image 20
mikeck Avatar answered Nov 10 '22 11:11

mikeck