What are the recommended methods for functional polymorphism in R?

Suppose I want to write a function in R , which is a function of several sufficient statistics for some data. For example, suppose a function called foo.func depends only on the average sample data sample. For convenience, I think users may want to switch to a foo.func sample of random variables (in this case, foo.func calculates the average value of the sample), or the sample itself means that all that foo.func requires. For efficiency reasons, the latter is preferable if several functions are called, such as foo.func , which can take the average value of the selection. In this case, the average value needs to be calculated only once (in the real problem that I have, the sample statistics in question can be computationally intensive).

In conclusion, I would like to write foo.func in order to be accessible for a beginner (to transmit data, to let the function calculate sufficient statistics), as well as an expert (to compare previously sufficient performance statistics and pass them to). What are the recommended methods for doing this? Do I have a boolean flag? A few arguments? Some ways to do this may be:

 #optional arguments foo.func <- function(xdata, suff.stats=NULL) { if (is.null(suff.stats)) { suff.stats <- compute.suff.stats(x) } #now operate on suff.stats } 

or

 #flag input foo.func <- function(data.or.stat, gave.data=TRUE) { if (gave.data) { data.or.stat <- compute.suff.stats(data.or.stat) } #now operate on data.or.stat } 

I am inclined to the first, I think

+8
polymorphism r
source share
2 answers

You can also embed functions in arguments, for example:

 foo.func <- function(x, suff.stats = foo.func.suff.stat(x)){ # your code here } 

As an example:

 foo.func <- function(x, avg = mean(x)){ return(avg) } foo.func(1:20) foo.func(avg = 42) 

Alternatively, you can use the default NULL setting for various arguments and check for is.null(argument) or just check the missing(argument) value for each of them for every argument you could calculate.


Update 1: I made a mistake proposing to use the default value NA : it is much more convenient to use NULL . Using NA and is.na() will behave strangely for vector inputs, while NULL is just one object - it is impossible to create a vector of NULL values, so is.null(argument) behaves as expected. Apologies for forgetfulness.

+5
source share

The way R to implement polymorphism is carried out using CLOS (Common Lisp OO), where the methods are associated with generic functions (verbs), and not with classes (nouns). For example,

 > ## suprising that there is not an equivalent function in R > ## to propagate inheritance... > addclass <- function(x,classname) + structure(x,class=append(class(x),classname)) > > ## this should be your main function that does stuff > ## here, the identity function is assigned for example > dostuff <- identity > > ## define generic function and methods > foo <- function(x,...) + UseMethod("foo") > > foo.raw <- function(x,...) + dostuff(mean(x)) > > foo.stats <- function(x,...) + dostuff(x) > > ## define two types of inputs > x <- 1:10 > x <- addclass(x,"raw") > > y <- 5 > y <- addclass(y,"stats") > > ## apply > > foo(x) [1] 5.5 > foo(y) [1] 5 attr(,"class") [1] "numeric" "stats" 

The example used the R S3 OOP model, which, in my opinion, is quite sufficient; S4 is more modern and secure, but adds a lot of templates.

+7
source share

All Articles