I have noticed some behaviour in R's base::options() that I am unable to fully understand.
the following is fine:
> vals_vector
[1] "temp" "hum" "co2" "voc" "pm1" "pm2_5" "pm10"
> options("hum" = TRUE)
> if (getOption("hum")) {
print("stuff")
}
[1] "stuff"
And this is also fine:
> options(TEMP_ENABLE = "temp" %in% vals_vector)
> getOption("TEMP_ENABLE")
[1] TRUE
However the following does not work.
> options(as.character(vals_vector[1]) = TRUE)
Error: unexpected '=' in "options(as.character(vals_vector[1]) ="
> as.character(vals_vector[1])
[1] "temp"
> "temp"
[1] "temp"
Makes no sense. You can see, I have evaluated the argument and it's exactly the same is both cases. Just in one I've used the variable. My intention was to use a loop to set an option for each variable present in a data set. Why doesn't this work as expected?
CodePudding user response:
You can't use function calls as stand-ins for argument names in R. This is nothing to do with options
, it's just how the R parser works. Take the following example, using the function data.frame
.
data.frame(A_B = 2)
#> A_B
#> 1 2
Suppose we wanted to generate the name A_B
programmatically:
paste("A", "B", sep = "_")
#> [1] "A_B"
Looks good. But if we try to use this function call with the intention that its output is interpreted as an argument name, the parser will simply tell us we have a syntax error:
data.frame(paste("A", "B", sep = "_") = 2)
#> Error: unexpected '=' in "data.frame(paste("A", "B", sep = "_") ="
There are ways round this - with most base R functions we would create a named list programmatically and pass that as an argument list using do.call
:
mylist <- list(TRUE)
names(mylist) <- vals_vector[1]
do.call(options, mylist)
getOption("temp")
#> [1] TRUE
However, if you read the docs for options
, it says
Options can also be passed by giving a single unnamed argument which is a named list.
So a more concise idiom would be:
options(setNames(list(TRUE), vals_vector[1]))
getOption("temp")
#> [1] TRUE