假设我想编写一个函数,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
}
Run Code Online (Sandbox Code Playgroud)
要么
#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
}
Run Code Online (Sandbox Code Playgroud)
我想,我倾向于前者
实现多态的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"
Run Code Online (Sandbox Code Playgroud)
这个例子是使用R的S3OOP模型,我认为这是足够的; S4更现代和安全,但增加了很多样板.
您还可以将函数嵌入到参数中,如下所示:
foo.func <- function(x, suff.stats = foo.func.suff.stat(x)){
# your code here
}
Run Code Online (Sandbox Code Playgroud)
举个例子:
foo.func <- function(x, avg = mean(x)){
return(avg)
}
foo.func(1:20)
foo.func(avg = 42)
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用NULL各种参数的默认设置,并测试is.null(argument),或者只是检查missing(argument)您可能计算的每个参数的值.
更新1:我错误地建议使用默认值NA:它更适合使用NULL.对于向量输入使用NA和is.na()将表现奇怪,而NULL只是单个对象 - 无法创建NULL值向量,因此is.null(argument)行为与预期一致.为遗忘道歉.
| 归档时间: |
|
| 查看次数: |
2201 次 |
| 最近记录: |