【问题标题】:Arguments and classes for writing (generic) functions in R在 R 中编写(通用)函数的参数和类
【发布时间】:2012-01-15 20:11:56
【问题描述】:

我想用几个非常简单的函数制作一个小的 R 包。我使用的文献是“创建 R 包:教程”和“编写 R 扩展”。虽然我试过了,但我并不真正理解泛型函数和方法的概念以及如何处理不同函数内的参数。

这是我的代码的一个小例子:

#Make generic function
f <- function(x,...) UseMethod("newmethod")

#Default method
f.default <- function(a,b=5,c=3,...){
    out <- a+b+c
    class(out) <- "fclass"
}

# Print method
print.f <- function(x,...){
    cat("Result:")
    print(x)
}

# Summary method
summary.f <- function(object,...){
    res <- object
    class(res) <- "fsummary"
    print(res)
}

# Plot method
plot.f <-function(x,p=0.3,...){}

我有一个名为 f 的函数,默认为 f.default。实际上我的函数需要几个参数(没有一个被定义为 x),那么我必须如何制作我的通用函数? print 方法应该简单地打印 f.default 的输出(在这种简单的情况下类似于摘要输出)。 plot.f 方法使用 f.default 的输出和一个附加参数(强制性)。如何正确编写这些函数?通常的方法使用“object”和“x”之类的参数......但正如我所说,我的函数中不需要任何变量 x......我有点困惑......也许有人可以帮忙。

如果有人愿意帮助我解决这个问题,我也可以发送“真实”的 R 代码(不仅仅是这个虚构的例子)。

【问题讨论】:

  • 方法必须与泛型一致。如果您的泛型以参数x 开头,那么方法也必须如此。

标签: r function generics methods


【解决方案1】:

我已经修复了你的代码,并在我修复的内容上添加了一些 cmets...

更新 正如@Spacedman 指出的那样,“构造函数”函数可能不应该是通用的。但我会把它放在这里,以便您了解如何通用函数是如何完成的。

#Make generic function
# This is the "constructor" function...
# ... UseMethod should have the name of the function!
f <- function(x,...) UseMethod("f")

#Default method
# ... The class name should be the same as the constructor
f.default <- function(a,b=5,c=3,...){
    out <- a+b+c
    class(out) <- "f"
    out # must return the object out, not the class name!
}

# Print method
# The "f" part of "print.f" must be the same as the class!
print.f <- function(x,...){
    cat("Result for f: ")
    print(unclass(x)) # Must unclass to avoid infinite recursion
    # NextMethod(x) # Alternative, but prints the class attribute...
}

# Summary method
# Should return a summary object (and not print it!)
# Need a unique class for it ("fsummary")
summary.f <- function(object,...){
    res <- object
    class(res) <- "fsummary"
    res
}

# Now need to print the summary too:
print.fsummary <- function(x, ...) {
    cat("f summary!\n")
    # Nice summary print goes here...
}

# Plot method
plot.f <-function(x,p=0.3,...){ cat("PLOTTING!\n") }

# Try it out:

x <- f(3)
x # print x

y <- summary(x) # 
y # print summary

plot(x)

【讨论】:

  • 你使用了一个泛型构造函数,这不是必需的,但当你可能从不同类型的参数构造时很方便,因此 f(onething) 根据什么生成一个 'f'东西'是。它可能是您可能想要放入“as.f()”方法并保持构造函数相当专业的那种功能。 YMMV。
  • @Spacedman - 好点。我同意在大多数情况下构造函数应该是非泛型的。我更新了我的答案。
【解决方案2】:

你在这里陷入了正确的混乱......

首先,您的构造函数可能不应该是泛型/方法。比如:

makefclass = function(a,b,c){
        l = list(a=a,b=b,c=c)
        class(l)="fclass"
        return(l)
      }

那你就可以写print.fclass了:

print.fclass=function(x,...){
     cat("I'm an fclass!")
     cat("my abc is ",x$a,x$b,x$c,"\n")
}

然后你做:

> f=makefclass(1,2,3)
> f
I'm an fclass!my abc is  1 2 2 

希望对您有所帮助...

【讨论】:

  • 嗨,@spacedman,不知何故,你的回答让我更加困惑......我按照 ["Creating R Packages: A Tutorial, page 7][1] 中的示例进行操作。但到目前为止我读到的泛型必须具有与方法相同的参数,这就是我在示例中苦苦挣扎的地方... [1]:cran.r-project.org/doc/contrib/Leisch-CreatingPackages.pdf
  • "makefclass" 不是通用的。它不是一种方法。它只是一个返回 fclass 对象的函数。在我的示例中,对泛型的唯一引用是 print.fclass 是用于打印泛型的方法。 print 有 args (x,...),print.fclass 也有。
  • 非常感谢...我只是对泛型感到困惑,但我不需要设置任何泛型...谢谢,现在一切正常...
猜你喜欢
  • 2015-09-12
  • 1970-01-01
  • 2011-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多