美元运算符作为 sapply 的函数参数未按预期工作
Dollar operator as function argument for sapply not working as expected
我有以下列表
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
我是不是漏掉了什么明显的东西?
据我所知,这是两件事的结合。
第一,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
是一个变量(甚至还没有被赋值),$
将它与列表中元素的名称相匹配。
评价对比none
[[
计算其参数,而 $
不计算。 L[[a]]
获取 L
的组件,其名称保存在变量 a
中。 $
只是将参数名称本身作为字符串传递,因此 L$a
找到了 L
的 "a"
组件。 a
不被视为保存组件名称的变量 -- 只是一个字符串。
L[[b]]
returns 下面 L
的组件命名为 "a"
因为变量 b
的值为 "a"
而 L$b
returns 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
是怎么回事,请考虑这个例子。我们已经将 test_list
的每个元素都变成了一个 "foo"
对象,并定义了我们自己的 $.foo
和 [[.foo
方法,这些方法简单地显示了 R 通过 [=36 传递给方法的内容=] 参数:
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$...
并且 ...
未被评估,因此它将寻找一个名为 [= 的列表组件40=],当然,没有这样的组件,所以 whatever$...
是 NULL,因此问题的输出中显示的是 NULL。在第二种情况下 whatever[[[...]]
评估为 whatever[["a"]]
因此观察到的结果。
我有以下列表
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
我是不是漏掉了什么明显的东西?
据我所知,这是两件事的结合。
第一,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
是一个变量(甚至还没有被赋值),$
将它与列表中元素的名称相匹配。
评价对比none
[[
计算其参数,而 $
不计算。 L[[a]]
获取 L
的组件,其名称保存在变量 a
中。 $
只是将参数名称本身作为字符串传递,因此 L$a
找到了 L
的 "a"
组件。 a
不被视为保存组件名称的变量 -- 只是一个字符串。
L[[b]]
returns 下面 L
的组件命名为 "a"
因为变量 b
的值为 "a"
而 L$b
returns 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
是怎么回事,请考虑这个例子。我们已经将 test_list
的每个元素都变成了一个 "foo"
对象,并定义了我们自己的 $.foo
和 [[.foo
方法,这些方法简单地显示了 R 通过 [=36 传递给方法的内容=] 参数:
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$...
并且 ...
未被评估,因此它将寻找一个名为 [= 的列表组件40=],当然,没有这样的组件,所以 whatever$...
是 NULL,因此问题的输出中显示的是 NULL。在第二种情况下 whatever[[[...]]
评估为 whatever[["a"]]
因此观察到的结果。