如何在R中为自定义S3类编写c()函数

7
我正在用R语言编写一个S3类,它只是一个带有一些属性的整数。如果x1和x2是此类(称为“myclass”)的对象,则我希望c(x1, x2)返回一个向量,其中包含原始类定义和属性的myclass对象。然而,c()函数的文档行为是删除属性,因此似乎我需要编写自己的c.myclass()方法。我的问题是,我该如何做到这一点?
以下是问题的示例:
myclass <- function(x, n) structure(x, class="myclass", n=n)
x1 <- myclass(1, 5)
x2 <- myclass(2, 6)
c(x1, x2)
[1] 1 2

这里的结果只是一个数字类项目的向量,原始的n属性已经消失了。

在查看各种软件包的代码时,有时会看到以下代码,在其中我们需要保留类属性但不需要其他内容:

c.myclass <- function(..., recursive = F) {
    structure(c(unlist(lapply(list(...), unclass))), class="myclass")
}

很遗憾,我也无法让它正常工作。调用c.myclass(x1, x2)的结果是一个向量,向量本身具有“myclass”类,但向量中的每个项都具有数字类;我真的希望向量中的每个项都具有“myclass”类。实际上,我还需要升级此方法以保留其他属性(例如“myclass”中的属性“n”)。

2个回答

8

这里是一个例子,通过特定的方法对 c[ 进行操作,实现了你想要的功能(我认为是这样):

c.myclass <- function(..., recursive = FALSE) {
    dots <- list(...)
    ns <- sapply(dots, attr, which = "n")
    classes <- rep("myclass", length(dots))
    res <- structure(unlist(dots, recursive = FALSE), class = classes)
    attr(res, "n") <- ns
    res
}

`[.myclass` <- function (x, i) {
    y <- unclass(x)[i]
    ns <- attr(x, "n")[i]
    class(y) <- "myclass"
    attr(y, "n") <- ns
    y
}


myclass <- function(x, n) structure(x, class = "myclass", n = n)
x1 <- myclass(1, 5)
x2 <- myclass(2, 6)
c(x1, x2)
c(x1, x2)[2]

但这是一个权宜之计,因为我们需要管理处理额外属性的设置和子集以保存 n。这实际上只是一个数值向量,带有记录 n 的属性。

使用所有向量的通用类型列表可能更自然。但这更加复杂,也许上述方法已经足够?


4

这个确实可行,但我猜你认为每个向量元素都属于数字类别,是因为你做了类似于这样的操作:

foo <- c(x1, x2)
class(foo[1])
class(foo[2])

如果是这种情况,你想要提取元素并保留 myclass 属性,你需要编写一个子集方法 "[.myclass" 来保留属性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接