0

我想在 R 中做一件非常简单的事情——有一个算法,我可以很容易地用一组函数参数化。我很确定我可以做一些像鸭子类型的对象。这是非常简单的代码中显示的想法:

par1.generate <- function(n) {
  runif(n, min=0, max=1000)
}

par1.mean <- function(vec) {
  mean(vec)
}


par2.generate <- function(n) {
  round(runif(n, min=0, max=1000))
}

par2.mean <- function(vec) {
  mean(vec, trim=0.2)
}

#the "algorithm"

alg <- function(par) {
  v <- par.generate(10)
  par.mean(v)
}

alg(par1)
alg(par2)

如果我尝试运行此代码,我会得到类似

alg(par1) 中的错误:找不到函数“par.mean”

所以我想我的直觉方法行不通。

做这样的事情的R方式是什么?任务很简单,所以我希望语法尽可能简单——没有抽象类或类似的。

4

3 回答 3

2

另一种选择是使用函数列表。

par1 <- list(generate=par1.generate,mean=par1.mean)
par2 <- list(generate=par2.generate,mean=par2.mean)

alg <- function(par) {
  v <- par$generate(10)
  par$mean(v)
}

alg(par1)
[1] 495.2501
alg(par2)
[1] 481
于 2013-03-25T21:00:47.997 回答
1

S3 风格的函数调度确实有点让人联想到鸭式打字。您可以定义一个通用函数名称(下例中的“声音”),并为每个类覆盖不同的函数。根据参数的类属性,R 将选择适当的函数。特别阅读 UseMethod,它是 R 函数调度机制的中心。

改编自http://www.r-bloggers.com/the-s3-oop-system/的示例:

# Set up dispatch for the generic function sound: 
sound <- function(x) UseMethod("sound", x)

# Methods are defined with a naming convention: method.class:
# This defines the method sound on class dog:
sound.dog <- function(x) "bark"
# Same for cow:
sound.cow <- function(x) "moo"
# Fallback:
sound.default <- function(x) "animal sound"

# The methods function can find out which classes a generic function was designed for:
> methods("sound")
[1] sound.cow     sound.default sound.dog

# R looks for methods in the order in which they appear in the class vector until it found the appropriate method to operate on.
# This makes multiple-inheritance possible

> x <- structure("cat", class = c("cat", "dog", "cow"))
> sound(x)
[1] "bark"

但在我看来,您似乎希望获得 R 所没有的语言功能。R 是古怪的,有时只是没有一种漂亮的做事方式。

于 2013-03-25T21:03:10.383 回答
1

使用match.fun名称并将其作为字符串传递:

alg <- function(par) {
    v <- (match.fun(paste(par,"generate",sep=".")))(10)
    (match.fun(paste(par,"mean",sep=".")))(v)
}

我得到:

# > alg("par1")
# [1] 615.5656
# > alg("par2")
# [1] 509

还有一些更复杂的选项,使用表达式和符号,即在语言上进行计算。请告诉您是否对此类事情感兴趣,我们可以提供更多帮助。

于 2013-03-25T20:49:44.127 回答