tags:

views:

335

answers:

3

Hello.

I'm trying to write a function to do a particular job (in my case, analyse a data set for outliers) so the first things I want to do is look at how other people have done similar jobs.

I can do this to load a particular package and examine the code of a function, but some functions seem to depend on what class of object you throw at it

>library(outliers)
> fix(outlier)

function (x, opposite = FALSE, logical = FALSE) 
{
    if (is.matrix(x)) 
        apply(x, 2, outlier, opposite = opposite, logical = logical)
    else if (is.data.frame(x)) 
        sapply(x, outlier, opposite = opposite, logical = logical)
    else {
        if (xor(((max(x) - mean(x)) < (mean(x) - min(x))), opposite)) {
            if (!logical) 
                min(x)
            else x == min(x)
        }
        else {
            if (!logical) 
                max(x)
            else x == max(x)
        }
    }
}

How can you look at the code of something that changes depending on the object ?

Edit:

OK, Palm <- face. The function I used as an example just calls itself, but allt he code is there... I have seen other examples (but can't think of any offhand) where the function did do other things depending on the class of the object thrown at it, so the question stands, even though it's a bad example !

+4  A: 

When you say

the function did do other things depending on the class of the object thrown at it

you are already at the heart of the S3 dispatch mechanism! So I would recommend reading a programming book on R as e.g.

  • (classic but dated) Venables/Ripley "S Programming",
  • Gentleman "Bioinformatics with R",
  • Brown/Murdoch "First Course in Statistical Programming with R",
  • Chambers "Software for Data Analysis: Programming with R",

or other resources from this SO question on R books along with an example package or two from the rich set of CRAN packages.

Dirk Eddelbuettel
+3  A: 

For example, plot() will do different things depending on the object. You can see the specific plot functions (called methods) using plot.ts(), plot.lm(), etc. i.e., plot() will call plot.ts() if a ts object is passed. In general, plot.xxx() is applied to objects of class xxx. If there is no specific method for the class, then plot.default() is used.

The function plot() is called a generic function because it can apply to many different classes. Other common generic functions are summary(), print() and predict().

As Dirk says, it is well worth reading the documentation on S3 methods and classes.

Rob Hyndman
And, in case you're curious, you can access all of the methods of any of these functions just by entering methods(functionname). Try methods(print), for example, if you'd like to have your mind blown.
Matt Parker
+3  A: 

My thought process for finding function code tends to be:

First, type the name of the function

Case 1: It shows the code

Great, you're done.

Example: diag

Case 2: The function comes up as a one line UseMethod statement

You have an S3 method. Type methods(fnname) to see available methods, then getAnywhere(fnname.myclass).

Example: mean

methods(mean)
getAnywhere(mean.default)
Case 3: The function contains a .Internal or .Primitive statement

The function is written in C, for improved performance. Download a copy of the R source code and extract the tarball. Search in the src directory for the function name.

EDIT: You can also search for the file using Google or Yahoo site search.

site:https://svn.r-project.org/R/trunk/src functionname

End EDIT

Example: qnorm

A simple windows search for "qnorm" in the src directory of the R source code reveals the file qnorm.c, which contains the function definition.

EDIT: qnorm.c is also the top result from the search

site:https://svn.r-project.org/R/trunk/src qnorm

End EDIT

Case 4: Still can't find the function

It's probably a method of an S4 class.

Type class(myobj) to find the class.

Type showMethods(class="myclass") to find available methods for that class.

Type getMethods("fnname", "myclass").

Example: plot pixmap

This requires the pixmap package.

library(pixmap)
pixie <- pixmap(1:12, nrow=3, ncol=4)
class(pixie)   #"pixmap"
showMethods(class="pixmap")
getMethod("plot", "pixmap")
Richie Cotton
Very helpful, thanks.
Matt Parker