我有一些自定义类,例如:
setClass("foo", slots = c(mat = "matrix"))
我想处理foo
个对象的列表是如何“不公开”的。
mat <- matrix(rnorm(16), 4)
foo <- new("foo", mat = mat)
unlist(list(foo))
我想也许为c
创建方法(我认为这些方法被使用但可能不正确),unlist
可以解决问题。
S3版
#' @export
unlist <- function(x, ...) UseMethod("unlist", x)
#' @export
unlist.default <- base::unlist
#' @method unlist foo
#' @export
unlist.foo <- function(x, ...){
print("called foo unlist")
}
S4版
#' @export
setMethod("unlist",
signature = "foo",
function(x, recursive = TRUE, use.names = TRUE){
print("call foo unlist")
})
c
功能
#' @export
setMethod("c",
signature = "foo",
function(x, ..., recursive = FALSE){
print("called foo c")
})
但我直接使用c
时才会看到确认消息:
c(foo)
[1] "called foo c"
unlist
只返回没有打印消息的同一对象
unlist(list(foo))
[[1]]
An object of class "foo"
Slot "mat":
[,1] [,2] [,3] [,4]
[1,] 0.6711541 -0.2783441 -0.4707375 -0.23060105
[2,] 0.7408401 0.4076826 2.2757187 -0.48547413
[3,] 1.8640581 0.3610619 -0.4632473 -0.06498348
[4,] -0.5595930 0.6679157 -0.8142456 0.27499963
如果我拨打unlist(foo)
,我会收到打印消息,但我需要将其应用于foo
个对象的列表。关于我如何取消列表处理列表中的自定义类的任何想法?
最终,我希望以下内容返回TRUE
:
all.equal(unlist(list(foo)), unlist(list(mat)))
答案 0 :(得分:0)
恐怕这是不可能的。 unlist
根据列表中各个元素的类型确定其输出的类型。如果所有元素都是原子的,就像唯一的元素是foo
(矩阵)一样,它对它的参数做了一些事情 - 强制公共原子向量的参数(只有一个)并忘记它的大多数属性(例如尺寸)。但是,它不会将恰好基于原子向量的S4对象(如foo
)视为原子向量:因此这些S4对象在结果中保持不变,结果将是类型列表。因此,在unlist
上调用list(foo)
会返回list(foo)
。该行为在C(do_unlist
中的bind.c
)中实现,在我看来与文档一致。
要模仿unlist
的可能用法子集中的所需行为,可以为foo
对象列表实现新类,为{{1}定义list
然后为这个list-of-foo类定义一个新的foo
,其行为类似于unlist的默认C实现在原子向量列表上的行为(我还没有尝试过)。