Flounderer
Flounderer

Reputation: 652

What causes this weird behaviour in the randomForest.partialPlot function?

I am using the randomForest package (v. 4.6-7) in R 2.15.2. I cannot find the source code for the partialPlot function and am trying to figure out exactly what it does (the help file seems to be incomplete.) It is supposed to take the name of a variable x.var as an argument:

library(randomForest)
data(iris)

rf <- randomForest(Species ~., data=iris)
x1 <- "Sepal.Length"
partialPlot(x=rf, pred.data=iris, x.var=x1)
# Error in `[.data.frame`(pred.data, , xname) : undefined columns selected

partialPlot(x=rf, pred.data=iris, x.var=as.character(x1))
# works!

typeof(x1)
# [1] "character"

x1 == as.character(x1)
# TRUE

# Now if I try to wrap it in a function...
f <- function(w){
  partialPlot(x=rf, pred.data=iris, x.var=as.character(w))
}

f(x1)
# Error in as.character(w) : 'w' is missing

Questions:

1) Where can I find the source code for partialPlot?

2) How is it possible to write a function which takes a string x1 as an argument where x1 == as.character(x1), but the function throws an error when as.character is not applied to x1?

3) Why does it fail when I wrap it inside a function? Is partialPlot messing with environments somehow?

Tips/ things to try that might be helpful for solving such questions by myself in future would also be very welcome!

Upvotes: 2

Views: 768

Answers (1)

Rich Scriven
Rich Scriven

Reputation: 99331

The source code for partialPlot() is found by entering

randomForest:::partialPlot.randomForest 

into the console. I found this by first running

methods(partialPlot)

because entering partialPlot only tells me that it uses a method. From the methods call we see that there is one method, and the asterisk next to it tells us that it is a non-exported function. To view the source code of a non-exported function, we use the triple-colon operator :::. So it goes

package:::generic.method

Where package is the package, generic is the generic function (here it's partialPlot), and method is the method (here it's the randomForest method).

Now, as for the other questions, the function can be written with do.call() and you can pass w without a wrapper.

f <- function(w) {
    do.call("partialPlot", list(x = rf, pred.data = iris, x.var = w))
}

f(x1)

This works on my machine. It's not so much environments as it is evaluation. Many plotting functions use some non-standard evaluation, which can be handled most of the time with this do.call() construct.

But note that outside the function you can also use eval() on x1.

partialPlot(x = rf, pred.data = iris, x.var = eval(x1))

I don't really see a reason to check for the presence of as.character() inside the function. If you can leave a comment we can go from there if you need more info. I'm not familiar enough with this package yet to go any further.

Upvotes: 5

Related Questions