假设我有一个data.frames列表
dflist <- list(data.frame(a=1:3), data.frame(b=10:12, a=4:6))
Run Code Online (Sandbox Code Playgroud)
如果我想从列表中的每个项目中提取第一列,我可以这样做
lapply(dflist, `[[`, 1)
# [[1]]
# [1] 1 2 3
#
# [[2]]
# [1] 10 11 12
Run Code Online (Sandbox Code Playgroud)
为什么我不能以同样的方式使用"$"函数
lapply(dflist, `$`, "a")
# [[1]]
# NULL
#
# [[2]]
# NULL
Run Code Online (Sandbox Code Playgroud)
但这些都有效:
lapply(dflist, function(x) x$a)
`$`(dflist[[1]], "a")
Run Code Online (Sandbox Code Playgroud)
我意识到在这种情况下可以使用
lapply(dflist, `[[`, "a")
Run Code Online (Sandbox Code Playgroud)
但我正在使用一个似乎不允许索引的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
Run Code Online (Sandbox Code Playgroud)
Jos*_*ien 28
对于第一个示例,您可以这样做:
lapply(dflist, `$.data.frame`, "a")
Run Code Online (Sandbox Code Playgroud)
对于第二个,使用slot()
访问器功能
lapply(mylist, "slot", "tab")
Run Code Online (Sandbox Code Playgroud)
我不确定为什么方法调度在第一种情况下不起作用,但该Note
部分?lapply
确实解决了它的原始函数的borked方法调度的这个问题,如$
:
Note:
[...]
For historical reasons, the calls created by ‘lapply’ are
unevaluated, and code has been written (e.g., ‘bquote’) that
relies on this. This means that the recorded call is always of
the form ‘FUN(X[[i]], ...)’, with ‘i’ replaced by the current
(integer or double) index. This is not normally a problem, but it
can be if ‘FUN’ uses ‘sys.call’ or ‘match.call’ or if it is a
primitive function that makes use of the call. This means that it
is often safer to call primitive functions with a wrapper, so that
e.g. ‘lapply(ll, function(x) is.numeric(x))’ is required to ensure
that method dispatch for ‘is.numeric’ occurs correctly.
Run Code Online (Sandbox Code Playgroud)
MrF*_*ick 13
因此,似乎这个问题更多地与$
它有关,以及它通常如何将未加引号的名称作为第二个参数而不是字符串.看看这个例子
dflist <- list(
data.frame(a=1:3, z=31:33),
data.frame(b=10:12, a=4:6, z=31:33)
)
lapply(dflist,
function(x, z) {
print(paste("z:",z));
`$`(x,z)
},
z="a"
)
Run Code Online (Sandbox Code Playgroud)
我们看到了结果
[1] "z: a"
[1] "z: a"
[[1]]
[1] 31 32 33
[[2]]
[1] 31 32 33
Run Code Online (Sandbox Code Playgroud)
所以该z
值设置为"a",但$
不评估第二个参数.所以它返回"z"列而不是"a"列.这导致了这组有趣的结果
a<-"z"; `$`(dflist[[1]], a)
# [1] 1 2 3
a<-"z"; `$`(dflist[[1]], "z")
# [1] 31 32 33
a<-"z"; `$.data.frame`(dflist[[1]], a)
# [1] 31 32 33
a<-"z"; `$.data.frame`(dflist[[1]], "z")
# [1] 31 32 33
Run Code Online (Sandbox Code Playgroud)
当我们调用$.data.frame
直接我们绕过,要调度发生在原语之前(其附近发生的标准deparsing 这里在源).
添加的捕获lapply
是它通过...
机制传递函数的参数.例如
lapply(dflist, function(x, z) sys.call())
# [[1]]
# FUN(X[[2L]], ...)
# [[2]]
# FUN(X[[2L]], ...)
Run Code Online (Sandbox Code Playgroud)
这意味着在$
调用时,它会将...
字符串转义为字符串"..."
.这解释了这种行为
dflist<- list(data.frame(a=1:3, "..."=11:13, check.names=F))
lapply(dflist, `$`, "a")
# [[1]]
# [1] 11 12 13
Run Code Online (Sandbox Code Playgroud)
当你尝试使用...
自己时也会发生同样的事情
f<-function(x,...) `$`(x, ...);
f(dflist[[1]], "a");
# [1] 11 12 13
`$`(dflist[[1]], "a")
# [1] 1 2 3
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2333 次 |
最近记录: |