R简单的鸭型对象用方法

时间:2013-03-25 20:41:39

标签: r oop

我想在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方式是什么?任务很简单,所以我希望语法尽可能简单 - 没有抽象类或类似的。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

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

答案 2 :(得分:1)

S3样式函数调度确实让人想起鸭子打字。您可以定义通用函数名称(以下示例中的“声音”),并覆盖每个类的不同函数。根据参数的class属性,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是古怪的,有时候只是没有一种漂亮的做事方式。