2

When using S3 or S4 classes in R, it's common to set a class as generic my_generic and then use dots for each subtype my_generic.my_type. Lately, I've been seeing this pattern, but using commas instead of periods my_generic,my_type. The problem is that I can't use the help operator ? or enter the function name in the console because the comma is treated as an error. Is there a workaround? I've tried using backticks, but it doesn't work.

An example of this is the draw method in the ComplexHeatmap package:

methods(draw)
[1] draw.colorkey             draw.details       draw,HeatmapAnnotation-method 
[4] draw,HeatmapList-method draw,Heatmap-method      draw.key                      
draw,SingleAnnotation-method

Doing ?draw.colorkey works, but ?draw,HeatmapAnnotation-method doesn't.

Joris Meys
  • 106,551
  • 31
  • 221
  • 263
nachocab
  • 13,328
  • 21
  • 91
  • 149
  • 2
    Maybe `?"draw,HeatmapAnnotation-method"`. – lmo Mar 30 '17 at 14:11
  • What about `do.call()`? The doc says it should work with function _names_. And `help()` works with strings too. – PlasmaBinturong Mar 30 '17 at 14:14
  • @lmo Thanks! That works. However, is there a way to access the function code, just like when I type `draw.colorkey` without parenthesis? – nachocab Mar 30 '17 at 14:16
  • @lmo It says `not found` so maybe there is no way to access those comma-methods. I'd like to understand what the comma convention represents – nachocab Mar 30 '17 at 14:25

1 Answers1

6

First of all, it is terribly bad practice to call methods directly, especially with S4. The "functions with a comma" you're looking at, are actually S4 methods.

Help pages

To find the help page (if it exists), you can use quotation marks like this:

?"draw,Heatmap-method"

But success is not guaranteed. This heavily depends on whether the author of the package has separate help files for the methods, or used the correct aliases. In this particular case, you see that on the help page ?draw the author of the package added a couple of links to the specific methods.

Find all S4 methods

To get an idea about all the S4 methods alone , use showMethods instead of methods.

> library(ComplexHeatmap)
> showMethods("draw")
Function: draw (package ComplexHeatmap)
object="Heatmap"
object="HeatmapAnnotation"
object="HeatmapList"
object="SingleAnnotation"

See the internal code of a method

To get the actual method so you can see the internal code, use getMethod:

getMethod(draw, signature = "Heatmap")
Method Definition:

function (object, ...) 
{...
    }
    .local(object, ...)
}
<environment: namespace:ComplexHeatmap>

Signatures:
        object   
target  "Heatmap"
defined "Heatmap"

Use a specific S4 method (but don't really)

You can assign the result of that call and use that as a function:

mat = matrix(rnorm(80, 2), 8, 10)
mat = rbind(mat, matrix(rnorm(40, -2), 4, 10))
rownames(mat) = letters[1:12]
colnames(mat) = letters[1:10]

ht = Heatmap(mat)
myMethod <- getMethod(draw, signature = "Heatmap")

myMethod(ht)

But you shouldn't try to call a method directly. The result of that last call is the exact same as

draw(ht)

So you better use the generic function and let the dispatching do its work.

Joris Meys
  • 106,551
  • 31
  • 221
  • 263
  • Excellent, thank you! My goal is not to use the method directly, but rather to be able to easily see the source code – nachocab Mar 30 '17 at 14:37
  • 2
    @nachocab you're welcome. I just added that for reference as a warning for future readers. After I saw the mentioning of `get` and `do.call` in the comments, I wanted to make sure people wouldn't think that calling S4 methods directly would be even remotely smart. With S3 there are cases where calling a method instead of a generic is warranted, so I can imagine people wanting to try that out with S4 as well :-) – Joris Meys Mar 30 '17 at 14:40
  • Based on @JorisMeys comment, perhaps it would also be smart to change the name of the question from "how to call a function..." to "how to reference a function..." – dww Mar 30 '17 at 14:51