1

Suppose I have an object x from class foo (representing some intervals):

x <- c("0;100", "0;20", "10;40", "10;40")
attr(x, "class") <- "foo"

table(x) orders the elements of x alphabetically:

0;100  0;20 10;40 
    1     1     2 

but I as default, would prefer to order x according to the length of the intervals. I expected that

table.foo <- function(x, ...) table(unclass(x), ...)[c(2, 3, 1)]
# or the sake of simplicity the way to find the ordering is not shown

leading to

table.foo(x)
0;20 10;40 0;100 
   1     2     1 

would do the job. Unfortunately, as far as I see it, table isn't a generic function (in contrast to e.g. plot), so running table(x) would not call table.foo(x). Is there a way to make table generic or more general: to make a function that will be called instead of table? I tried setGeneric("table", table.foo) but it seems not to be what I want: firstly, it produces infinite recursion, as table.foo will be called in every case, even if the object passed to table is not of class foo and secondly, it seems to be a local effect (on the computer running the code) for table, but not a general effect for table.foo, which shall be distributed by a package.

Qaswed
  • 3,649
  • 7
  • 27
  • 47
  • 1
    I couldn't find a question close enough to confidently flag as duplicate, but there are several questions and answers on this site on this topic. You can see how to make a non-S3 generic base function into a S3 generic function that would behave as you expect [here](https://stackoverflow.com/a/48392351/8386140), [here](https://stackoverflow.com/questions/42236092/), and [here](https://stackoverflow.com/questions/42986174/cant-fix-warning-when-redefining-log-as-a-generic?noredirect=1&lq=1) (for example). I would also read [this chapter of Advanced R](http://adv-r.had.co.nz/OO-essentials.html). – duckmayr Jan 30 '18 at 17:21

1 Answers1

0

The first link to an answer on a different question, both (link and answer) provided by @duckmayr, solved the issue. So here is the hardly modified code from @duckmayr's answer:

#' My new table function
#'
#' My new table function able to handle objects of class foo.
#'
#' @param x an object
#' @param ... other arguments
#'
#' @rdname table
#' @export
table <- function(x, ...) {
    UseMethod('table', x)
}

#' @rdname table
#' @export
table.foo <- function(x, ...) {
    table(unclass(x), ...)[c(2, 3, 1)]
}

#' @rdname table
#' @export
table.default <- function(x, ...) {
    return(base::table(x, ...))
}
Qaswed
  • 3,649
  • 7
  • 27
  • 47