我在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
这里的结果只是类numeric的项向量,原来的n属性消失了。
查看各种包的代码,我有时会看到如下代码,其中我们需要保留class属性,而不是其他:
c.myclass <- function(..., recursive = F) {
structure(c(unlist(lapply(list(...), unclass))), class="myclass")
}
不幸的是,我也无法让这个工作。调用c.myclass(x1,x2)的结果是一个向量,其中向量本身具有类“myclass”,但是向量中的每个项都有类numeric;我真的希望向量中的每个项都有类“myclass”。在实践中,我还需要升级此方法以保留其他属性(例如myclass中的属性“n”)。
答案 0 :(得分:7)
以下是通过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
的属性的数字向量。
使用所有向量的通用列表可能更自然。在你的情况下,更多涉及的位可能就足够了吗?
答案 1 :(得分:4)
这确实有效,但我假设你得出结论,每个向量元素都有类数字,因为你做的是这样的:
foo <- c(x1, x2)
class(foo[1])
class(foo[2])
如果是这种情况,并且您希望提取的元素保留myclass
属性,则需要编写子集方法"[.myclass"
以保留属性。