Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use eval(substitute()) on multiple expressions

I asked a question before about How to take in text/character argument without quotes. In the scenario I provided in that question, the number of arguments is fixed, so the number of eval(substitute()) I use in function definition corresponds to the number of arguments I have.

Now I have a scenario where I have one argument, for example factors (see below), and the user can specify multiple column names without using quotes around them - i.e., they will use factor1 instead of "factor1". And I would like to evaluate each of the column names provided by the user.

foo<-function(data.frame, factors){

}

Question 1: I wonder if there is a way to apply eval(substitute()) to multiple expressions when the number of expressions can vary.

As pointed out, eval(substitute()) can be potentially dangerous and can fail under certain circumstances.

Question 2: so is there a more elegant way to deal with the issue other than using quoted column names as shown below:

foo<-function(data.frame, factors){
   output<-data.frame[, factors]
   output
}
foo(data.frame=dataset, factors=c("factor1", "factor2"))
like image 823
Alex Avatar asked Mar 20 '13 15:03

Alex


1 Answers

First of all, in the example you've provided, I'd definitely prefer using quoted column names. One thing in their favor is that they'll allow useful indirection like the following:

XX <- c("cyl", "mpg")
foo(mtcars, XX)

That said, in case you do want to pass in a vector of unquoted symbols, this addresses your Question 2.

foo <- function(data, factors) {
    jj <- as.character(substitute(factors)[-1])
    data[,jj]
}

head(foo(data = mtcars, factors = c(cyl, mpg)))
#                   cyl  mpg
# Mazda RX4           6 21.0
# Mazda RX4 Wag       6 21.0
# Datsun 710          4 22.8
# Hornet 4 Drive      6 21.4
# Hornet Sportabout   8 18.7
# Valiant             6 18.1
like image 112
Josh O'Brien Avatar answered Nov 11 '22 15:11

Josh O'Brien