我有一些自定义类,例如:
setClass("foo", slots = c(mat = "matrix"))
Run Code Online (Sandbox Code Playgroud)
我想处理一个foo对象列表是如何"不公开"的.
mat <- matrix(rnorm(16), 4)
foo <- new("foo", mat = mat)
unlist(list(foo))
Run Code Online (Sandbox Code Playgroud)
我想也许创建方法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")
}
Run Code Online (Sandbox Code Playgroud)
S4版
#' @export
setMethod("unlist",
signature = "foo",
function(x, recursive = TRUE, use.names = TRUE){
print("call foo unlist")
})
Run Code Online (Sandbox Code Playgroud)
c 功能
#' @export
setMethod("c",
signature = "foo",
function(x, ..., recursive = FALSE){
print("called foo c")
})
Run Code Online (Sandbox Code Playgroud)
但我c直接使用时只看到确认消息:
c(foo)
[1] "called foo c"
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
如果我打电话unlist(foo)然后我得到打印消息,但我需要将它应用于foo对象列表.关于我如何取消列表处理列表中的自定义类的任何想法?
最终我希望以下内容返回TRUE:
all.equal(unlist(list(foo)), unlist(list(mat)))
Run Code Online (Sandbox Code Playgroud)
恐怕这是不可能的。unlist根据它获取的列表中各个元素的类型确定其输出的类型。foo如果所有元素都是原子的,就像唯一的元素是(矩阵)的情况一样,它会对它的参数做一些事情——将参数强制为公共原子向量(只有一个)并忘记它的大部分属性(例如维度)。但是,它不会将foo恰好基于原子向量的 S4 对象(如 )视为原子向量:因此,这些 S4 对象将在结果中保持完整,并且结果将是列表类型。所以unlist呼吁list(foo)回报list(foo)。该行为是在 C 中实现的do_unlist,bind.c在我看来与文档一致。
为了模仿 的可能用法的子集中的所需行为unlist,可以为foo对象列表实现一个新类,定义listfor foo,然后unlist为此 list-of-foo 类定义一个新类,其行为类似于默认的 C unlist 的实现在原子向量列表上运行(我没有尝试过)。