Monday, August 13, 2007

Get source codes for invisible functions or internal functions in R

As a R user, you might want to the original code of a function. But sometimes, the function just won't show the original code in the R console because it is either an internal function or an invisible function of a package. Or in the third case, R just spells out the message like this:

> model.matrix
function (object, ...)
UseMethod("model.matrix")


There are ways to get the original code of functions like those aforementioned. Functions for this matters are getS3method (for S3 methods), getMethod (for S4 methods) and getAnywhere. Among these three getAnywhere is the most general function. I will do a demo using getAnywhere.

Suppose I want to get the original code for model.matrix. But using getAnywhere only get:

> getAnywhere("model.matrix")
A single object matching 'model.matrix' was found
It was found in the following places
package:stats
namespace:stats
with value

function (object, ...)
UseMethod("model.matrix")


So we know there must be some suffix after model.matrix. In most cases, the suffix is a class name. To know what the suffix of model.matrix is, we use methods to get the information. If it is

> methods(model.matrix)
[1] model.matrix.default model.matrix.lm

Or if you want to know methods that related to a generic function:

showMethods("generic.function")

Now we know there are two related functions to the model.matrix. Therefore we can get the original code of these two using getAnywhere.

getAnywhere(model.matrix.lm)

If you know a function is an internal function of a package, you can also get it using getAnywhere.

For example, there is an internal function called sd.scalar in "arm" package, to get the code:

> getAnywhere(sd.scalar)
A single object matching 'sd.scalar' was found
It was found in the following places
namespace:arm
with value

function (x, ...)
{
sqrt(var(as.vector(x), ...))
}


To get a S4 method for a specific class, simply type:

getMethod("method", "class")

3 comments:

The Ponds said...

This was really helpful, thank you!

Humility Consulting said...

I'm not sure that works for .Internal or .Primitive functions (sum, strsplit, for, …).

http://stackoverflow.com/questions/14035506/how-to-see-the-source-code-of-r-internal-or-primitive-function

^ That question redirects people to Uwe Ligges' article in http://cran.r-project.org/doc/Rnews/Rnews_2006-4.pdf.

Brad Horn said...

A good article...but incomplete.

For functions with .Internal we see above a reference to the old Rnews article. For .Internal, the article assumes that R_HOME still has an src directory, which it doesnt.

So even the good links provided here fail to point the way to source code.

...and they say R is open source? Not after looking for the source code for hours!