3

我想知道 R 中的 S3 类,是否可以选择定义默认输出元素并保持其余元素隐藏。例如,假设我们有一个玩具函数,它计算某些事物并将它们作为 S3 类报告回来,如下所示:

toy <- function(x){
  resA <- mean(x)
  resB <- length(x)

  output <- list(resA=resA, resB=resB, x=x)
  class(output) <- "toy"
  output
}

当我们现在通过

res <- toy(c(1:10))
res

正如预期的那样,我们将整个列表作为输出。但是如果我们也定义了一个 S3 打印方法

`print.toy` <- function(x){
  print(x$resA)
}

我们可以为 print 提供一个标准输出,它隐藏了不必要的信息(在这种情况下resBx)并且用户只能看到resA。但这可能会导致一些混乱,当你想对你的对象应用进一步的计算时toy,例如

res <- toy(c(1:10))
res 
# Produces an error
res + 1 
# Accesses the correct variable of class toy:
res$resA + 1

我现在的问题是,有没有办法将列表项定义resA为 S3 类的标准值,如果未指定变量,则应采用该标准值,以便res + 1调用也能正常工作?

感谢您阅读本文。

4

2 回答 2

4

一种方法是使用向量+属性而不是列表。如果您有一个应该像常规向量一样工作的主要数据,以及一些额外的元数据,这是最合适的。

toy <- function(x) {
  resA <- mean(x)
  resB <- length(x)

  structure(resA, x = x, b = resB, class = "toy")
}
print.toy <- function(x, ...) {
  print(as.vector(x))
}
t <- toy(1:10)
t + 1
# [1] 6.5

您还需要覆盖[,因为默认方法不保留属性。

于 2013-03-06T14:32:53.187 回答
2

正如@Ari 提到的,您可能必须执行以下操作:

`+.toy` <- function(a, b) { 
     # you should check for class/mode/is.atomic here if necessary
     a$resA <- a$resA + b
     a
}

t <- toy(1:10)
t + 1
# [1] 6.5
于 2013-03-06T07:22:59.317 回答