Search code examples
rmethodsr-s4

How to call a function that contains a comma in R?


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.


Solution

  • 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.