r - Check expression argument of function -


when writing functions important check type of arguments. example, take following (not useful) function performing subsetting:

data_subset = function(data, date_col) {        if (!true %in% (is.character(date_col) | is.expression(date_col))){         stop("input variable date of wrong format")       }        if (is.character(date_col)) {         x <- match(date_col, names(data))       } else  x <- match(deparse(substitute(date_col)), names(data))          sub <- data[,x] } 

i allow user provide column should extracted character or expression (e.g. column called "date" vs. date). @ beginning check input date_col either character value or expression. however, 'is.expression' not work:

error in match(x, table, nomatch = 0l) : object '...' not found 

since deparse(substitute)) works if 1 provides expressions thought 'is.expression' has work well. wrong here, can give me hint?

i think not looking is.expression is.name.

the tricky part type of date_col , check if of type character if not of type name. if called is.character when it's name, evaluated, typically resulting in error because object not defined.

to this, short circuit evaluation can used: in

if(!(is.name(substitute(date_col)) || is.character(date_col))) 

is.character called if is.name returns false.

your function boils down to:

data_subset = function(data, date_col) {    if(!(is.name(substitute(date_col)) || is.character(date_col))) {      stop("input variable date of wrong format")    }    date_col2 <- as.character(substitute(date_col))   return(data[, date_col2]) } 

of course, use if(is.name(…)) convert character when date_col name.

this works:

testdf <- data.frame(col1 = rnorm(10), col2 = rnorm(10, mean = 10), col3 = rnorm(10, mean = 50), rnorm(10, mean = 100))  data_subset(testdf, "col1") # ok data_subset(testdf, col1) # ok data_subset(testdf, 1) # error in data_subset(testdf, 1) : input variable date of wrong format 

however, don't think should this. consider following example:

var <- "col1" data_subset(testdf, var) #  error in `[.data.frame`(data, , date_col2) : undefined columns selected  col1 <- "col2" data_subset(testdf, col1) # gives content of column 1, not column 2. 

though "works designed", confusing because unless reading function's documentation 1 expect col1 in first case , col2 in second case.

abusing famous quote:

some people, when confronted problem, think “i know, i'll use non-standard evaluation.” have 2 problems.

hadley wickham in non-standard evaluation:

non-standard evaluation allows write functions extremely powerful. however, harder understand , program with. providing escape hatch, consider both costs , benefits of nse before using in new domain.

unless expect large benefits allowing skip quotes around name of column, don't it.


Comments