[Rd] Making custom unary operators in R

Trevor.L.Davis at frb.gov Trevor.L.Davis at frb.gov
Thu Mar 13 22:50:10 CET 2008


Hello,

Is there a way to define a custom unary operator in R (other than making a 
class and 'overloading' the normal unary operators in R)?  The 
documentation seems to suggest that only custom binary operators are 
possible with the ``%abc%``construct but I was wondering whether any one 
has done so.  None of the RSiteSearch or RSeek queries I posed suggested 
that this question had been asked before but if it has, a link to the 
relevant discussion thread would be wonderful.

For example in the J language the ``! `` sign is a unary operator for the 
factorial function and a binary operator for the choose function so I 
would like to be able to define a similar operator like this::

    '%!%' <-  function(e1, e2) {
           if (missing(e2)) factorial(e1)
           else choose(e2, e1)
           }

The binary version of the operator works fine:

    > 2 %!% 4
    [1] 6

But the unary one doesn't (which is perfectly understandable since there 
is no indication in any documentation I have seen that suggests it 
should):::

    > %!% 4
    Error: unexpected SPECIAL in "%!%"

The source code for the '?' operator almost seems to suggest that a mixed 
unary / binary non-primitive R function is possible::

    > get('?')
    function (e1, e2)
    {
        e1Expr <- substitute(e1)
        if (missing(e2)) {
            if (is.call(e1Expr))
                return(.helpForCall(e1Expr, parent.frame()))
            if (is.name(e1Expr))
                e1 <- as.character(e1Expr)
            eval(substitute(help(TOPIC), list(TOPIC = e1)))
        }
        else {
            if (is.name(e1Expr))
                e1 <- as.character(e1Expr)
            e2Expr <- substitute(e2)
            if (is.name(e2Expr))
                e2 <- as.character(e2Expr)
            else if (is.call(e2Expr) && identical(e1, "method"))
               return(.helpForCall(e2Expr, parent.frame(), FALSE))
            topic <- topicName(e1, e2)
            doHelp <- .tryHelp(topic)
            if (inherits(doHelp, "try-error")) {
                stop(gettextf("no documentation of type '%s' and topic 
'%s' (or error in processing help)",
                    e1, e2), domain = NA)
            }
        }
    }
    <environment: namespace:utils>

I was playing around with the idea of the ways one could try build a J 
interpreter with R and it seemed like being able to define custom unary / 
binary operators like that could be convenient.

Thanks,

Trevor Davis
Federal Reserve Board of Governors



More information about the R-devel mailing list