假设我想在R
中编写一个函数,这是一些关于某些数据的足够统计数据的函数。例如,假设函数,称之为foo.func
仅取决于数据样本的样本均值。为方便起见,我认为用户可能希望传递给foo.func
随机变量的样本(在这种情况下foo.func
计算样本均值),或样本均值本身,就是foo.func
所需要的一切。出于效率的原因,如果有多个函数如foo.func
被调用可以采用样本均值,则优选后者。在这种情况下,平均值只需计算一次(在我遇到的实际问题中,所讨论的样本统计数据可能是计算密集型的)。
总之,我想写foo.func
以便初学者可以访问(传递数据,让函数计算足够的统计数据)以及专家(预先计算足够的统计数据以提高效率并通过他们)。推荐的做法是什么?我是否传递了逻辑标志?多个参数?一些方法可能是:
#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
}
或
#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
}
我倾向于前者,我想
答案 0 :(得分:9)
实现多态的R方式是通过CLOS(Common Lisp的OO)模型,其中方法与泛型函数(动词)而不是类(名词)相关联。例如,
# 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"
这个例子是使用R的S3
OOP模型,我认为这个模型已经足够了; S4
更现代,更安全,但增加了许多样板。
答案 1 :(得分:7)
您还可以将函数嵌入到参数中,如下:
foo.func <- function(x, suff.stats = foo.func.suff.stat(x)){
# your code here
}
举个例子:
foo.func <- function(x, avg = mean(x)){
return(avg)
}
foo.func(1:20)
foo.func(avg = 42)
或者,您可以为各种参数使用默认设置NULL
,并测试is.null(argument)
,或者只为每个可能计算的参数检查missing(argument)
的值
更新1:我错误地建议使用默认值NA
:使用NULL
更合适。使用NA
和is.na()
对于向量输入会表现得很奇怪,而NULL
只是一个对象 - 无法创建NULL值向量,因此is.null(argument)
的行为与预期相同。为遗忘道歉。