Skip to content

partial plot global scope

David Chudzicki edited this page Sep 15, 2013 · 1 revision

People give me a bit of crap at work for using R, as they should. I use other tools too, but there are things I like about R. This experience yesterday didn't help my case:

R's randomForest package has a neat function partialPlot ("partial" is used in the same sense as in "partial derivative") that can help you understand what your "black box" ensemble of decision trees is doing:

library(randomForest)
data(airquality)
airquality <- na.omit(airquality)
ozone.rf <- randomForest(Ozone ~ ., airquality, importance = TRUE)
partialPlot(ozone.rf, airquality, "Temp")

I wanted to use the partialPlot function inside function I was writing. For simplicity, here I'll illustrate with a function that does nothing but call partialPlot. This doesn't work:

myPartialPlotFunction <- function(variable) {
    partialPlot(ozone.rf, airquality, variable)
}
myPartialPlotFunction("Temp")

Nor this:

myPartialPlotFunction("Temp")

The reason is that partialPlot thinks that variable is the name of my variable!

Get is a handy little function for working around this kind of thing. You pass it a strong, and it gets the value stored there. I use it a lot with ggplot2, which has the same kind of issue with getting your arguments that store variable names interpreted correctly. This should work:

myPartialPlotFunction <- function(variable) {
    partialPlot(ozone.rf, airquality, get("variable"))
}
myPartialPlotFunction("Temp")

But it didn't work!: Error in get("variable") : object 'variable' not found.

After a bunch of searching, I found that someone else had encountered the same problem:

What I've realized is that partialPlots, for some reason, always looks to the Global environment when evaluating the "x.var" argument. So any variables created within a function ... are not seen. From what I can tell, this only seems to be true for the "x.var" argument. Other arguments seem to be able to take variables from within the function's environment/namespace. My solution was to just modify my original function to kick a copy of "i" out to Global...

So this works:

myPartialPlotFunction <- function(variable) {
    I_REALLY_SHOULDNT_HAVE_TO_MAKE_THIS_GLOBAL <<- variable
    partialPlot(ozone.rf, airquality, get("I_REALLY_SHOULDNT_HAVE_TO_MAKE_THIS_GLOBAL"))
}
myPartialPlotFunction("Temp")

I haven't dug into why partialPlot looks only in the global environment, but I suspect it has something to do with the contortions involved in making both partialPlot(ozone.rf, airquality, "Temp") and partialPlot(ozone.rf, airquality, Temp) work.