R: recover commands & track methods

http://tolstoy.newcastle.edu.au/R/help/05/09/12506.html

From: Prof Brian Ripley
Date: Thu 22 Sep 2005 - 19:10:08 EST

The original reply was deliberately (I guess) vague. (I've removed the history, as attributions had already been removed, in violation of copyright law. If you cite someone, you MUST credit the author.)

Sometimes a little knowledge is a dangerous thing, and we have had a number of partially true answers.

Spreading confusion between the S4 classes of the 'methods' package and the (sometimes called S3) classes of base R is also dangerous. The R documentation refers to S3 methods and classes unless otherwise stated (and in the methods package documentation). Please follow that lead.

On Thu, 22 Sep 2005, Spencer Graves wrote:

> Is there general documentation on a procedure to follow to:
>
> (a) Find what methods are available for a particular class of
> objects?

?methods, unless you mean an S4 class.

Be careful here: methods `for a particular class' are not all that might be dispatched, as methods for classes the object inherits from may also be used. Thus "lm" methods may be invoked for "glm" objects, and you may need to call methods() for all the classes the object inherits from.

> (b) Find what classes of objects have methods defined for a partilar
> generic function?

?methods, unless you mean S4 classes (and that help page leads you to the right place for those).

> (c) Get the code that's actually used?

getAnywhere() on the asterisked results of (a) or (b).

For a specific generic and a specific class, getS3method().

[There is a potential gap here as the "bar" method for class "foo" need not be called foo.bar(). So guessing the name may not work, but getS3method("foo", "bar") will. AFAIK there are no live examples of this.]

> For example, I recently needed to access numbers associated with an
> object of class "lmer". Sundar suggested I use with 'getMethod("show",
> "summary.lmer")'. However, this doesn't work with the example below.

(I think that was intended to refer to the default method for princomp, which is not an S4 generic in base R.

> methods("princomp")

[1] princomp.default* princomp.formula*

Non-visible functions are asterisked
> getAnywhere("princomp.default") # works
> getS3Method("princomp", "default") # works
> showMethods("princomp")

Function "princomp":

)

show() is an S4 generic, not an S3 generic. ?methods points you to how to explore S4 generics.

> library(lme4)

... (and drink some coffee while you wait)
> methods(show)

no methods were found
Warning message:
function 'show' appears not to be generic in: methods(show)
> showMethods("show")

Function "show":
object = "ANY"
object = "traceable"
object = "ObjectsWithPackage"
object = "MethodDefinition"
object = "MethodWithNext"
object = "genericFunction"
object = "classRepresentation"
object = "ddenseMatrix"
object = "Matrix"
object = "lmer"
object = "summary.lmer"
object = "VarCorr"
object = "sparseMatrix"
object = "lmList"

> selectMethod("show", "summary.lmer")
Method Definition:

function (object) ...

Here getMethod() will also work, but selectMethod() is more likely to find `the code that's actually used'.

========================================
David W pointed me to this more complete discussion in Rnews.

http://www.r-project.org/doc/Rnews/Rnews_2006-4.pdf

R Help Desk
Accessing the Sources R Code Sources
by Uwe Ligges
ISSN 1609-3631
Vol. 6/4, October 2006

He urges readers to consult the source code often!

Some tidbits I don't want to forget:

These sections are direct quotes:

"
Code Hidden in a Namespace

In some cases, a seemingly missing function is called
within another function. Such a function might sim-
ply be hidden in a namespace (Tierney, 2003). Type
getAnywhere("FunctionName") in order to find it.
This function reports which namespace a function
comes from, and one can then look into the sources of
the corresponding package. This is particularly true
for S3 methods such as, for example, plot.factor:
R> plot.factor
Error: object "plot.factor" not found
R> getAnywhere("plot.factor")
A single object matching ’plot.factor’ was found
It was found in the following places
registered S3 method for plot from namespace
graphics
namespace:graphics
with value
### [function code omitted] ###
The file that contains the code of plot.factor is
‘$R HOME/src/library/graphics/R/plot.R’.
S3 and S4

As another example, suppose that we have the ob-
ject lmObj, which results from a call to lm(), and we
would like to find out what happens when the object
is printed. In that case, a new user probably types
R> print
in order to see the code for printing. The frustrating
result of the call is simply:
function (x, ...)
UseMethod("print")

The more experienced user knows a call to
UseMethod() indicates that print() is an S3 generic
and calls the specific method function that is appro-
priate for the object of class class(x). It is possible
to ask for available methods with methods(print).
The function of interest is the S3 method print.lm()
from namespace stats (the generic itself is in the base
package namespace).

A method hidden in a names-
pace can be accessed (and therefore printed) directly
using the ::: operator as in stats:::print.lm.

In order to understand and change S4 related
sources, it is highly advisable to work directly
with a package’s source files. For a quick look,
functions such as
getClass(),
getGeneric(), and
getMethod()
are available. The following example
prints the code of the show() method for mle objects
from the stats4 package:
R> library("stats4")
R> getMethod("show", "mle")

"

About pauljohn

Paul E. Johnson is a Professor of Political Science at the University of Kansas. He is an avid Linux User, an adequate system administrator and C programmer, and humility is one of his greatest strengths.
This entry was posted in R. Bookmark the permalink.