Keywords: R | function | source code | debugging | method dispatch
Abstract: This article provides a detailed guide on how to view the source code of R functions, covering S3 and S4 method dispatch systems, unexported functions, and compiled code. It explains techniques using methods(), getAnywhere(), and accessing source repositories for effective debugging and learning.
Introduction
In R programming, inspecting the source code of functions is essential for understanding internal logic, debugging errors, or learning advanced techniques. Many R functions use various dispatch mechanisms or call hidden code, and this article guides you through step-by-step examples on how to access these sources.
S3 Method Dispatch System
R's S3 system relies on generic function dispatch based on object classes. For instance, the output of function t shows UseMethod("t"), indicating it is a generic function. To list all related methods, use the methods function.
> methods(t)
[1] t.data.frame t.default t.ts*
Non-visible functions are asteriskedAsterisked functions are not exported from their package namespace but can be accessed via the ::: operator or getAnywhere(). For example, to view the source of t.ts:
> getAnywhere(t.ts)
A single object matching ‘t.ts’ was found
It was found in the following places
registered S3 method for t from namespace stats
namespace:stats
with value
function (x)
{
cl <- oldClass(x)
other <- !(cl %in% c("ts", "mts"))
class(x) <- if (any(other))
cl[other]
attr(x, "tsp") <- NULL
t(x)
}
<bytecode: 0x294e410>
<environment: namespace:stats>This code has been rewritten for clarity while preserving the original logic.
S4 Method Dispatch System
The S4 system offers a more formal method dispatch, with functions like with displaying standardGeneric. Use showMethods to list available methods.
> showMethods(chol2inv)
Function: chol2inv (package base)
x="ANY"
x="CHMfactor"
x="denseMatrix"
x="diagonalMatrix"
x="dtrMatrix"
x="sparseMatrix"To view the source code of a specific method, use getMethod with the full signature.
> getMethod("chol2inv", "diagonalMatrix")
Method Definition:
function (x, ...)
{
chk.s(...)
tcrossprod(solve(x))
}
<bytecode: 0x000000000ea2cc70>
<environment: namespace:Matrix>Functions Calling Unexported Functions
Some functions call unexported functions from their namespace. For example, ts.union calls .cbindts and .makeNamesTs, which can be accessed via :::.
> stats:::.makeNamesTs
function (...)
{
l <- as.list(substitute(list(...)))[-1L]
nm <- names(l)
fixup <- if (is.null(nm))
seq_along(l)
else nm == ""
dep <- sapply(l[fixup], function(x) deparse(x)[1L])
if (is.null(nm))
return(dep)
if (any(fixup))
nm[fixup] <- dep
nm
}
<bytecode: 0x38140d0>
<environment: namespace:stats>Functions Calling Compiled Code
When functions call .C, .Call, .Fortran, .External, .Internal, or .Primitive, they involve compiled code. To view the source, access the R or package source code.
For packages, download the source using download.packages() and untar it.
download.packages(pkgs = "Matrix", destdir = ".", type = "source")
untar(download.packages(pkgs = "Matrix", destdir = ".", type = "source")[,2])For base packages or the R interpreter, refer to the R source tree on GitHub or Subversion.
Conclusion
By mastering S3 and S4 method dispatch, accessing unexported functions, and viewing compiled code, users can effectively understand and debug R functions. These techniques not only enhance programming skills but also support the development of custom functions.