我有以下列表
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
我错过了一些明显的东西吗?
答案 0 :(得分:11)
评估与无
[[
评估其参数,而$
则不。 L[[a]]
获取L
的组件,其名称保存在变量a
中。 $
只是将参数名称本身作为字符串传递,因此L$a
会找到"a"
的{{1}}组件。 L
不被视为包含组件名称的变量 - 只是一个字符串。
a
下方L[[b]]
返回名为L
的{{1}}组件,因为变量"a"
的值为b
,而"a"
则返回组件L$b
L
名为"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
方法,这些方法只显示R通过{{1}传递给方法的内容参数:
name
在第一种情况下发生的事情是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$...
未被评估,因此它将寻找一个名为{{1}的列表组件当然,没有这样的组件,因此...
为NULL,因此在问题的输出中显示了NULL。在第二种情况下,"..."
评估为whatever$...
因此观察到的结果。
答案 1 :(得分:6)
从我能够确定它是两件事的组合。
首先,the second element of $
is matched but not evaluated so it cannot be a variable。
其次,当参数传递给函数时,它们被赋值给函数调用中的相应变量。传递给sapply
"a"
时,会将其分配给变量,因此不再使用$
。我们可以通过运行
sapply("a", print)
[1] "a"
a
"a"
这可能导致像这样的特殊结果
sapply(test_list, function(x, a) {`$`(x, a)})
[1] 1 3
尽管a
是一个变量(甚至没有分配)$
将其与列表中元素的名称相匹配。