我有以下清单
test_list=list(list(a=1,b=2),list(a=3,b=4))
我想用列表元素名称提取所有元素a
.
我可以通过这样做
sapply(test_list,`[[`,"a")
这给了我正确的结果
#[1] 1 3
当我尝试使用Rs美元运算符时$
,我得到了NULL
sapply(test_list,`$`,"a") #[[1]] #NULL # #[[2]] #NULL
但是,如果我在单个元素上使用它,test_list
它会按预期工作
`$`(test_list[[1]],"a") #[1] 1
我错过了一些明显的东西吗?
评估与无
[[
评估其论点而$
不是. L[[a]]
获取L
其名称保存在变量中的组件a
. $
只是将参数名称本身作为字符串传递,因此L$a
找到"a"
组件L
. a
不被视为包含组件名称的变量 - 只是一个字符串.
下面L[[b]]
返回L
named 的组件,"a"
因为变量b
具有值,"a"
而L$b
返回L
named 的组件,"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
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"
在第一种情况下发生的sapply
是调用whatever$...
和...
不进行评估所以它将寻找一个字面命名的列表组件"..."
,当然,没有这样的组件所以whatever$...
是NULL因此在输出中显示的NULL题.在第二种情况下,whatever[[[...]]
评估whatever[["a"]]
观察结果.
从我能够确定它是两件事的组合.
首先,第二个元素$
匹配但未评估,因此它不能是变量.
其次,当参数传递给函数时,它们被赋值给函数调用中的相应变量.传递给sapply
"a"
分配给变量时,将不再使用$
.我们可以通过运行来看到这一点
sapply("a", print) [1] "a" a "a"
这可能导致像这样的特殊结果
sapply(test_list, function(x, a) {`$`(x, a)}) [1] 1 3
尽管a
是变量(甚至没有分配),$
但它与列表中元素的名称相匹配.