cry*_*111 13 r dollar-sign lapply sapply
我有以下清单
test_list=list(list(a=1,b=2),list(a=3,b=4))
Run Code Online (Sandbox Code Playgroud)
我想用列表元素名称提取所有元素a.
我可以通过这样做
sapply(test_list,`[[`,"a")
Run Code Online (Sandbox Code Playgroud)
这给了我正确的结果
#[1] 1 3
Run Code Online (Sandbox Code Playgroud)
当我尝试使用Rs美元运算符时$,我得到了NULL
sapply(test_list,`$`,"a")
#[[1]]
#NULL
#
#[[2]]
#NULL
Run Code Online (Sandbox Code Playgroud)
但是,如果我在单个元素上使用它,test_list它会按预期工作
`$`(test_list[[1]],"a")
#[1] 1
Run Code Online (Sandbox Code Playgroud)
我错过了一些明显的东西吗?
G. *_*eck 11
评估与无
[[评估其论点而$不是. L[[a]]获取L其名称保存在变量中的组件a. $只是将参数名称本身作为字符串传递,因此L$a找到"a"组件L. a不被视为包含组件名称的变量 - 只是一个字符串.
下面L[[b]]返回Lnamed 的组件,"a"因为变量b具有值,"a"而L$b返回Lnamed 的组件,"b"因为该语法b不被视为变量,而是被视为自身传递的字符串.
L <- list(a = 1, b = 2)
b <- "a"
L[[b]] # same as L[["a"]] since b holds a
## [1] 1
L$b # same as L[["b"]] since b is regarded as a character string to be passed
## [1] 2
Run Code Online (Sandbox Code Playgroud)
sapply
现在我们已经理解了$和[[看到正在发生的事情的关键区别] sapply考虑这个例子.我们已经将每个元素都test_list变成了一个"foo"对象,并定义了我们自己的方法$.foo和[[.foo方法,它们只是通过name参数显示R传递给方法的内容:
foo_list <- test_list
class(foo_list[[1]]) <- class(foo_list[[2]]) <- "foo"
"$.foo" <- "[[.foo" <- function(x, name) print(name)
result <- sapply(foo_list, "$", "a")
## "..."
## "..."
result2 <- sapply(foo_list, "[[", "a")
## [1] "a"
## [1] "a"
Run Code Online (Sandbox Code Playgroud)
在第一种情况下发生的sapply是调用whatever$...和...不进行评估所以它将寻找一个字面命名的列表组件"...",当然,没有这样的组件所以whatever$...是NULL因此在输出中显示的NULL题.在第二种情况下,whatever[[[...]]评估whatever[["a"]]观察结果.
从我能够确定它是两件事的组合.
其次,当参数传递给函数时,它们被赋值给函数调用中的相应变量.传递给sapply "a"分配给变量时,将不再使用$.我们可以通过运行来看到这一点
sapply("a", print)
[1] "a"
a
"a"
Run Code Online (Sandbox Code Playgroud)
这可能导致像这样的特殊结果
sapply(test_list, function(x, a) {`$`(x, a)})
[1] 1 3
Run Code Online (Sandbox Code Playgroud)
尽管a是变量(甚至没有分配),$但它与列表中元素的名称相匹配.