I want to look at the source code for a function to see how it works. I know I can print a function by typing its name at the prompt:
> t
function (x)
UseMethod("t")
<bytecode: 0x2332948>
<environment: namespace:base>
In this case, what does UseMethod("t")
mean? How do I find the source code that's actually being used by, for example: t(1:10)
?
Is there a difference between when I see UseMethod
and when I see standardGeneric
and showMethods
, as with with
?
> with
standardGeneric for "with" defined from package "base"
function (data, expr, ...)
standardGeneric("with")
<bytecode: 0x102fb3fc0>
<environment: 0x102fab988>
Methods may be defined for arguments: data
Use showMethods("with") for currently available ones.
In other cases, I can see that R functions are being called, but I can't find the source code for those functions.
> ts.union
function (..., dframe = FALSE)
.cbind.ts(list(...), .makeNamesTs(...), dframe = dframe, union = TRUE)
<bytecode: 0x36fbf88>
<environment: namespace:stats>
> .cbindts
Error: object '.cbindts' not found
> .makeNamesTs
Error: object '.makeNamesTs' not found
How do I find functions like .cbindts
and .makeNamesTs
?
In still other cases, there's a bit of R code, but most of work seems to be done somewhere else.
> matrix
function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)
{
if (is.object(data) || !is.atomic(data))
data <- as.vector(data)
.Internal(matrix(data, nrow, ncol, byrow, dimnames, missing(nrow),
missing(ncol)))
}
<bytecode: 0x134bd10>
<environment: namespace:base>
> .Internal
function (call) .Primitive(".Internal")
> .Primitive
function (name) .Primitive(".Primitive")
How do I find out what the .Primitive
function does? Similarly, some functions call .C
, .Call
, .Fortran
, .External
, or .Internal
. How can I find the source code for those?
UseMethod("t")
is telling you thatt()
is a (S3) generic function that has methods for different object classes.The S3 method dispatch system
For S3 classes, you can use the
methods
function to list the methods for a particular generic function or class."Non-visible functions are asterisked" means the function is not exported from its package's namespace. You can still view its source code via the
:::
function (i.e.stats:::t.ts
), or by usinggetAnywhere()
.getAnywhere()
is useful because you don't have to know which package the function came from.The S4 method dispatch system
The S4 system is a newer method dispatch system and is an alternative to the S3 system. Here is an example of an S4 function:
The output already offers a lot of information.
standardGeneric
is an indicator of an S4 function. The method to see defined S4 methods is offered helpfully:getMethod
can be used to see the source code of one of the methods:There are also methods with more complex signatures for each method, for example
To see the source code for one of these methods the entire signature must be supplied, e.g.
It will not suffice to supply the partial signature
Functions that call unexported functions
In the case of
ts.union
,.cbindts
and.makeNamesTs
are unexported functions from thestats
namespace. You can view the source code of unexported functions by using the:::
operator orgetAnywhere
.Functions that call compiled code
Note that "compiled" does not refer to byte-compiled R code as created by the compiler package. The
<bytecode: 0x294e410>
line in the above output indicates that the function is byte-compiled, and you can still view the source from the R command line.Functions that call
.C
,.Call
,.Fortran
,.External
,.Internal
, or.Primitive
are calling entry points in compiled code, so you will have to look at sources of the compiled code if you want to fully understand the function. This GitHub mirror of the R source code is a decent place to start. The functionpryr::show_c_source
can be a useful tool as it will take you directly to a GitHub page for.Internal
and.Primitive
calls. Packages may use.C
,.Call
,.Fortran
, and.External
; but not.Internal
or.Primitive
, because these are used to call functions built into the R interpreter.Calls to some of the above functions may use an object instead of a character string to reference the compiled function. In those cases, the object is of class
"NativeSymbolInfo"
,"RegisteredNativeSymbol"
, or"NativeSymbol"
; and printing the object yields useful information. For example,optim
calls.External2(C_optimhess, res$par, fn1, gr1, con)
(note that'sC_optimhess
, not"C_optimhess"
).optim
is in the stats package, so you can typestats:::C_optimhess
to see information about the compiled function being called.Compiled code in a package
If you want to view compiled code in a package, you will need to download/unpack the package source. The installed binaries are not sufficient. A package's source code is available from the same CRAN (or CRAN compatible) repository that the package was originally installed from. The
download.packages()
function can get the package source for you.This will download the source version of the Matrix package and save the corresponding
.tar.gz
file in the current directory. Source code for compiled functions can be found in thesrc
directory of the uncompressed and untared file. The uncompressing and untaring step can be done outside ofR
, or from withinR
using theuntar()
function. It is possible to combine the download and expansion step into a single call (note that only one package at a time can be downloaded and unpacked in this way):Alternatively, if the package development is hosted publicly (e.g. via GitHub, R-Forge, or RForge.net), you can probably browse the source code online.
Compiled code in a base package
Certain packages are considered "base" packages. These packages ship with R and their version is locked to the version of R. Examples include
base
,compiler
,stats
, andutils
. As such, they are not available as separate downloadable packages on CRAN as described above. Rather, they are part of the R source tree in individual package directories under/src/library/
. How to access the R source is described in the next section.Compiled code built into the R interpreter
If you want to view the code built-in to the R interpreter, you will need to download/unpack the R sources; or you can view the sources online via the R Subversion repository or Winston Chang's github mirror.
Uwe Ligges's R news article (PDF) (p. 43) is a good general reference of how to view the source code for
.Internal
and.Primitive
functions. The basic steps are to first look for the function name insrc/main/names.c
and then search for the "C-entry" name in the files insrc/main/*
.It gets revealed when you debug using the debug() function. Suppose you want to see the underlying code in t() transpose function. Just typing 't', doesn't reveal much.
But, Using the 'debug(functionName)', it reveals the underlying code, sans the internals.
EDIT: debugonce() accomplishes the same without having to use undebug()
You can also try to use
print.function()
, which is S3 generic, to get the function write in the console.