首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么不对具有S4方法的as.list.default对象应用工作?

为什么不对具有S4方法的as.list.default对象应用工作?
EN

Stack Overflow用户
提问于 2014-09-27 22:33:50
回答 1查看 3.7K关注 0票数 6

假设我有一个类似向量的S4类:

代码语言:javascript
复制
.MyClass <- setClass("MyClass", representation(a="numeric", b="character"))

setMethod("[", c("MyClass", "numeric", "missing"), function(x, i, j, ...) {
  do.call(initialize, c(x, sapply(slotNames(x), function(y) slot(x, y)[i],
          simplify=FALSE)))
})

setMethod("length", "MyClass", function(x) length(x@a))

并且说我也为as.listas.list.default定义了方法

代码语言:javascript
复制
setGeneric("as.list")
setMethod("as.list", "MyClass",
          function(x) lapply(seq_along(x), function(i) x[i]))
setGeneric("as.list.default")
setMethod("as.list.default", "MyClass",
          function(x) lapply(seq_along(x), function(i) x[i]))

现在给出这个类的一个对象,myobj

代码语言:javascript
复制
myobj <- .MyClass(a=1:4, b=letters[1:4])

当我使用lapply时,它会抱怨:

代码语言:javascript
复制
> lapply(myobj, function(i) rep(i@b, i@a))
Error in as.list.default(X) : 
  no method for coercing this S4 class to a vector

但是,如果我使用as.list.default,则该函数提供所需的输出:

代码语言:javascript
复制
> lapply(as.list.default(myobj), function(i) rep(i@b, i@a))
[[1]]
[1] "a"

[[2]]
[1] "b" "b"
...

为什么lapply不工作,即使我已经为类定义了一个as.list.default的方法?

显然,我可以手动为类定义一个lapply方法,它可以很好地工作(下面),但是我想知道错误实际上是在哪里发生的。为什么lapply试图将我的对象强制为向量,即使它正在调用的函数应该将对象转换为列表?

代码语言:javascript
复制
setGeneric("lapply")
setMethod("lapply", c("MyClass", "function"), function(X, FUN, ...) {
  lapply(as.list(X), FUN, ...)
})
lapply(myobj, function(i) rep(i@b, i@a))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-27 23:28:47

?Methods帮助页面上看,一个可行的策略似乎是

代码语言:javascript
复制
#same
.MyClass <- setClass("MyClass", representation(a="numeric", b="character"))

setMethod("[", c("MyClass", "numeric", "missing"), function(x, i, j, ...) {
  do.call(initialize, c(x, sapply(slotNames(x), function(y) slot(x, y)[i],
          simplify=FALSE)))
})

setMethod("length", "MyClass", function(x) length(x@a))

#different
as.list.MyClass <-function(x) {
    lapply(seq_along(x), function(i) x[i])
}
setMethod("as.list", "MyClass", as.list.MyClass)

#test
myobj <- .MyClass(a=1:4, b=letters[1:4])
lapply(myobj, function(i) rep(i@b, i@a))

# [[1]]
# [1] "a"
# 
# [[2]]
# [1] "b" "b"
# 
# [[3]]
# [1] "c" "c" "c"
# 
# [[4]]
# [1] "d" "d" "d" "d"
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26079819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档