【问题标题】:Dollar operator as function argument for sapply not working as expected美元运算符作为 sapply 的函数参数未按预期工作
【发布时间】:2016-04-05 08:02:17
【问题描述】:

我有以下列表

test_list=list(list(a=1,b=2),list(a=3,b=4))

我想提取列表元素名称为a的所有元素。

我可以通过

sapply(test_list,`[[`,"a")

这给了我正确的结果

#[1] 1 3

当我尝试使用 Rs Dollar 运算符 $ 时,我得到 NULL

sapply(test_list,`$`,"a")
#[[1]]
#NULL
#
#[[2]]
#NULL

但是,如果我在 test_list 的单个元素上使用它,它会按预期工作

`$`(test_list[[1]],"a")
#[1] 1

我在这里遗漏了什么明显的东西吗?

【问题讨论】:

    标签: r lapply sapply dollar-sign


    【解决方案1】:

    评估与无

    [[ 计算它的参数,而 $ 没有。 L[[a]] 获取 L 的组件,其名称保存在变量 a 中。 $ 只是将参数名称本身作为字符串传递,因此 L$a 找到 L"a" 组件。 a 不被视为保存组件名称的变量——只是一个字符串。

    L[[b]] 下方返回名为 "a"L 的组件,因为变量 b 的值是 "a",而 L$b 返回 L 的组件,名为 "b",因为使用该语法 @ 987654339@不被视为变量,而是被视为字符串,它本身被传递。

    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 通过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$... 并且 ... 没有被评估,所以它会寻找一个字面上命名为 "..." 的列表组件,当然,还有没有这样的组件,所以whatever$... 是 NULL,因此问题的输出中显示了 NULL。在第二种情况下,whatever[[[...]] 的计算结果为 whatever[["a"]],因此是观察到的结果。

    【讨论】:

      【解决方案2】:

      据我所知,这是两件事的结合。

      首先,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 是一个变量(甚至还没有被赋值),$ 将它与列表中元素的名称相匹配。

      【讨论】:

      • 非常有趣的答案!它基本上表明 x="a";"$"(test_list[[1]],x); 已经给出了不正确的结果。
      • 另外,与您所说的类似,"$"(test_list[[1]],a) 给出了1,尽管没有定义对象a
      猜你喜欢
      • 2019-12-10
      • 2018-02-19
      • 2021-04-06
      • 2012-12-22
      • 2020-01-09
      • 1970-01-01
      • 2015-05-11
      • 2019-06-20
      相关资源
      最近更新 更多