0

Frequently when I am working with R and I want to find out what the function does, I type in the name of the function and scroll through the code. However, sometimes when I type in the name of the function I get a response that does not tell me anything.

> library(limma)
> plotMDS #can't get to the code
function (x, ...) 
UseMethod("plotMDS")
<environment: namespace:limma>
> limma:::plotMDS
function (x, ...) 
UseMethod("plotMDS")
<environment: namespace:limma>
> heatmap #im expecting something more like this
function (x, Rowv = NULL, Colv = if (symm) "Rowv" else NULL, 
    distfun = dist, hclustfun = hclust, reorderfun = function(d, 
        w) reorder(d, w), add.expr, symm = FALSE, revC = identical(Colv, 
        "Rowv"), scale = c("row", "column", "none"), na.rm = TRUE, 
    margins = c(5, 5), ColSideColors, RowSideColors, cexRow = 0.2 + 
        1/log10(nr), cexCol = 0.2 + 1/log10(nc), labRow = NULL, 
    labCol = NULL, main = NULL, xlab = NULL, ylab = NULL, keep.dendro = FALSE, 
    verbose = getOption("verbose"), ...) 
{
    scale <- if (symm && missing(scale)) 
        "none"
    else match.arg(scale)
/* ... many lines removed ... */
    }
    invisible(list(rowInd = rowInd, colInd = colInd, Rowv = if (keep.dendro && 
        doRdend) ddr, Colv = if (keep.dendro && doCdend) ddc))
}
<bytecode: 0x16199b8>
<environment: namespace:stats>

Thus, I was wondering if there is a way to import a package's namespace into the default namespace so I can look at code in functions (and debug things easier). I've been reading up on namespace but most of the time it is written for developers so it is talking about how to export namespaces for packages.

Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
yingw
  • 166
  • 8
  • you're right. This solved my problem of reading code but still wondering if its possible to put the whole package namespace into default namespace. – yingw Apr 03 '13 at 21:21

2 Answers2

3

plotMDS is the generic function. What you access via plotMDS and limma:::plotMDS is exactly the same thing, the latter just less-efficiently. What you want to get at are the methods for this generic function.

To see the list of method for plotMDS try

methods(plotMDS)

That will return a vector of function names. I can't install limma so here is what we see for the base plot generic [in my current session]:

> methods(plot)
 [1] plot.acf*            plot.correspondence* plot.data.frame*    
 [4] plot.decomposed.ts*  plot.default         plot.dendrogram*    
 [7] plot.density         plot.ecdf            plot.factor*        
[10] plot.formula*        plot.function        plot.hclust*        
[13] plot.histogram*      plot.HoltWinters*    plot.isoreg*        
[16] plot.lda*            plot.lm              plot.mca*           
[19] plot.medpolish*      plot.mlm             plot.ppr*           
[22] plot.prcomp*         plot.princomp*       plot.profile*       
[25] plot.profile.nls*    plot.ridgelm*        plot.spec           
[28] plot.stepfun         plot.stl*            plot.table*         
[31] plot.ts              plot.tskernel*       plot.TukeyHSD       

   Non-visible functions are asterisked

To access the code of non-starred functions we just enter the full function name, e.g.

> plot.density
function (x, main = NULL, xlab = NULL, ylab = "Density", type = "l", 
    zero.line = TRUE, ...) 
{
....

To see the code for starred functions/methods you need the pkg:::function structure, e.g. for the plot.data.frame method

> plot.data.frame
Error: object 'plot.data.frame' not found
> graphics:::plot.data.frame
function (x, ...) 
{
 ....

If you don't know which namespace a method belongs to, then use getAnywhere, e.g.

> getAnywhere(plot.data.frame)
A single object matching ‘plot.data.frame’ was found
It was found in the following places
  registered S3 method for plot from namespace graphics
  namespace:graphics
with value

function (x, ...) 
{
....

The printed results indicate the relevant namespace (in this case graphics) plus return the value of the function, or the code.

Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
  • yup this works, but still a bit curious about the pkg namespace -> default namespace ``` > methods(plotMDS) [1] plotMDS.default plotMDS.MDS > getAnywhere(plotMDS.MDS) A single object matching ‘plotMDS.MDS’ was found It was found in the following places package:limma registered S3 method for plotMDS from namespace limma namespace:limma with value function (x, labels = colnames(x$distance.matrix), col = NULL, cex = 1, dim.plot = x$dim.plot, xlab = paste("Dimension", dim.plot[1]), ylab = paste("Dimension", dim.plot[2]), ...) { /* more code here*/ ``` – yingw Apr 03 '13 at 21:34
  • There isn't a "default" namespace. All packages now must have their own namespace. It is up to the individual package maintainers to decide what is exported (i.e. visible) and what is not exported (i.e. not visible). – Gavin Simpson Apr 03 '13 at 21:52
0

This is a really crude alternative, but it does what was requested:

Firstly, copy the contents of the namespace to a list in the global environment:

L <- as.list(asNamespace("yourpackage"))

Now you can either navigate L or copy all its contents to equally named objects in the global environment with this:

invisible(lapply(names(L), function(x) eval(parse(text=paste0(x,"<-L[['",x,"']]")), globalenv())))

warning: this will overwrite whatever object you have defined with the same name! So use with care.

Ferdinand.kraft
  • 12,579
  • 10
  • 47
  • 69