【发布时间】:2018-11-03 18:56:15
【问题描述】:
假设我有一个 data.frames 列表
dflist <- list(data.frame(a=1:3), data.frame(b=10:12, a=4:6))
如果我想从列表中的每个项目中提取第一列,我可以这样做
lapply(dflist, `[[`, 1)
# [[1]]
# [1] 1 2 3
#
# [[2]]
# [1] 10 11 12
为什么我不能以同样的方式使用“$”函数
lapply(dflist, `$`, "a")
# [[1]]
# NULL
#
# [[2]]
# NULL
但这两个都有效:
lapply(dflist, function(x) x$a)
`$`(dflist[[1]], "a")
我意识到在这种情况下可以使用
lapply(dflist, `[[`, "a")
但我使用的 S4 对象似乎不允许通过 [[ 进行索引。例如
library(adegenet)
data(nancycats)
catpop <- genind2genpop(nancycats)
mylist <- list(catpop, catpop)
#works
catpop[[1]]$tab
#doesn't work
lapply(mylist, "$", "tab")
# Error in slot(x, name) :
# no slot of name "..." for this object of class "genpop"
#doesn't work
lapply(mylist, "[[", "tab")
# Error in FUN(X[[1L]], ...) : this S4 class is not subsettable
【问题讨论】:
-
这个作品
lapply(dflist, function(x) "$"(x, "a"))。 -
好问题。仅供参考,可以通过
methods("$",dflist[[1]])找到答案 -
好吧@Frank,并不是我不知道
$.data.frame的存在,我只是很惊讶这个问题是由方法调度引起的。我想不出在许多其他情况下您必须显式调用一种形式的泛型函数。 -
@MrFlick -- 我支持你。它必须(?)与
lapply()的奇怪的惰性评估方面有关,但由于其中一些(或者,实际上,全部)发生在 C 代码级别,我从来没有完全能够了解它在幕后所做的事情。 -
@JoshO'Brien 我认为这可能更多地与使用
$解析参数有关,而不是专门用于 lapply。请参阅此示例:f<-function(x,...) `$`(x, ...); f(dflist[[1]], "a"); `$`(dflist[[1]], "a")。这是因为$不是“典型”通用,而是.Primitive(),所以我敢打赌秘密在于here