Some functions in R
are able to take a data.frame
as an argument, while having separate arguments whom can take the names
of the data.frame
(without having to quote them as strings).
A concrete example of this is the function qplot
in the ggplot2
package:
myDF <- data.frame(values=rnorm(5*2), group=c(rep("A", 5), rep("B", 5)))
qplot(values, data=myDF, colour=group, geom="density")
qplot
is able to take values
and group
and know that they are columns of myDF
.
Now if I want to write a wrapper function that does some preprocessing before plotting, I lose that functionality:
# A silly example. But lets assume our dataframe has more than 1 group column
silly.wrapper <- function(dataframe, colour) {
dataframe$values <- dataframe$values*2
qplot(values*2, data=dataframe, geom="density", colour=colour)
}
now if i try to call silly.wrapper
and give it colour=group
it throws an error that the object group hasn't been declared (as you would expect):
# We have to call print because its a lattice plot so returned qplot won't render
# otherwise. Removing call to print still results in the same error.
print(silly.wrapper(myDF, colour=group))
Error in eval(expr, envir, enclos) : object 'group' not found
In addition: Warning message:
In eval(expr, envir, enclos) : restarting interrupted promise evaluation
I've also tried using ...
:
silly.wrapper <- function(dataframe, ...) {
dataframe$values <- dataframe$values*2
qplot(values*2, data=dataframe, geom="density", ...)
}
But get the same error message.
This leads me to a more general question: How does one write a function, like qplot
, that doesn't check for an object's existence until later, i.e. accessing it as a column of a dataframe?