6

我正在用 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”)。

4

2 回答 2

7

c这是一个示例,它(我认为)通过特定方法对and执行您想要的操作[

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

使用所有向量的泛型(列表)可能更自然。涉及更多的位,对于您的情况,上述内容可能就足够了吗?

于 2010-11-22T09:42:15.743 回答
4

这确实有效,但我假设您得出结论每个向量元素都具有类 numeric 因为您正在执行以下操作:

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

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

于 2010-11-22T02:00:07.627 回答