How to see the code for S4 methods in R

If you want to see the code for an S3 method (the older-style) in R it’s easy, you just need to type in the name of the method (with no brackets or parameters):

> ls
function (name, pos = -1, envir = as.environment(pos), all.names = FALSE, 
    pattern) 
{
    if (!missing(name)) {
        nameValue <- try(name)
        if (identical(class(nameValue), "try-error")) {
            name <- substitute(name)
            if (!is.character(name)) 
                name <- deparse(name)
            pos <- name
        }
        else pos <- nameValue
    }
    all.names <- .Internal(ls(envir, all.names))
    if (!missing(pattern)) {
        if ((ll <- length(grep("[", pattern, fixed = TRUE))) && 
            ll != length(grep("]", pattern, fixed = TRUE))) {
            if (pattern == "[") {
                pattern <- "\\["
                warning("replaced regular expression pattern '[' by  '\\\\['")
            }
            else if (length(grep("[^\\\\]\\[<-", pattern))) {
                pattern <- sub("\\[<-", "\\\\\\[<-", pattern)
                warning("replaced '[<-' by '\\\\[<-' in regular expression pattern")
            }
        }
        grep(pattern, all.names, value = TRUE)
    }
    else all.names
}

and the code for that method will be printed on the screen.

However, if you try the same thing on an S4 method (the newer, object-oriented style) then you get something more obtuse:

> # load the package I'm currently using (from bioconductor)
> library("Rsamtools")
Loading required package: IRanges

Attaching package: 'IRanges'

The following object(s) are masked from 'package:base':

    cbind, Map, mapply, order, paste, pmax, pmax.int, pmin, pmin.int, rbind, rep.int, table

Loading required package: GenomicRanges
Loading required package: Biostrings
> readPileup
standardGeneric for "readPileup" defined from package "Rsamtools"

function (file, ...) 
standardGeneric("readPileup")

Methods may be defined for arguments: file
Use  showMethods("readPileup")  for currently available ones.

However, this makes sense if you consider how S4 works. Because it allows method overloading, there could be multiple method definitions depending on the parameters given to the method at runtime (it’s signature). So to get correct method definition, you need to specify the signature as well.

Solution

Use showMethod to show all of method signatures that are defined for the method in question, and getMethod to retrieve the code for a particular method and signature:

> showMethods("readPileup")
Function: readPileup (package Rsamtools)
file="character"
file="connection"

Here we can see that for readPileup there are two method definitions, one with signature "character" and one with signature "connection". Then if you call getMethod for one of these signatures you will be able to see the code:

> getMethod("readPileup", "connection")
Method Definition:

function (file, ...) 
{
    .local <- function (file, ..., variant = c("SNP", "indel", 
        "all")) 
    {
        variant <- match.arg(variant)
        switch(variant, SNP = , all = .readPileup_SNP(file = file, 
            ..., variant = variant), indel = .readPileup_indel(file = file, 
            ...))
    }
    .local(file, ...)
}


Signatures:
        file        
target  "connection"
defined "connection"

Note that if showMethods displays “inherited from” below a particular signature, then this isn’t a full method definition, but is just inherited from the definition for another signature (and you should call getMethod on that signature instead).

Advertisements

About this entry