【问题标题】:How does the `[<-` function work in R?`[<-` 函数在 R 中如何工作?
【发布时间】:2016-05-10 10:24:33
【问题描述】:

例如,我见过一些人使用 [&lt;- 作为带有波兰符号的函数

x <- matrix(1:4, nrow = 2)
`[<-`(x, 1, 2, 7)

返回

     [,1] [,2]
[1,]    1    7
[2,]    2    4

我已经尝试过使用 [&lt;- 一点,看起来像这样使用它会打印类似 x[1,2] &lt;- 7 的结果,而无需实际执行分配。但我无法确定这个函数实际上是做什么的,因为为?"[" 提供的文档只是顺便提及它,我无法在谷歌或 SO 中搜索“[

是的,我知道实际上使用这可能是一个可怕的想法,我只是为了更好地理解R而感到好奇。

【问题讨论】:

  • 这更像是 R 将 x[1,2] &lt;- 7 转换为 x &lt;- '[&lt;-'(x, 1, 2, 7)
  • 如果你了解[函数和&lt;-函数,那么[&lt;-函数就很有意义了。试试[(x,1,2)。试试&lt;-(a,1)
  • 我没有看到这个重复。我认为的问题是为什么[&lt;- 实际上不会影响符号/命名对象x 中的子赋值。这似乎不是提名副本中提出的问题。
  • "[&lt;-" 是一个返回相应修改对象的函数。 "[&lt;-"(x, i, value) 似乎就是这样做的。要查看显式 "[&lt;-" 调用和 x[i] &lt;- value 的解析方式之间的区别,也许可以参见 '*tmp*' = "tmp"; x = 1:3; x[2] &lt;- 0; x; get("*tmp*") VS '*tmp*' = "tmp"; x = 1:3; "[&lt;-"(x, 2, 0); x; get("*tmp*"),如 here 所述。

标签: r slice assignment-operator


【解决方案1】:

这是你需要做的事情才能坚持下去:

 `<-`(    `[`(   x, 1, 2), 7)  # or x <- `[<-`(   x, 1, 2, 7)
 x
     [,1] [,2]
[1,]    1    7
[2,]    2    4

基本上发生的事情是[ 正在创建指向x 的行列位置的指针,然后是&lt;-(这实际上是assign 的同义词,也可以在中缀表示法中使用)正在做实际的“永久”任务。不要被误导认为这是一个引用调用分配。我有理由确定仍然会创建一个临时值 x

您的版本确实进行了子分配(从它返回的内容可以看出),但该分配仅在调用 [&lt;- 的本地环境中,不包含全局环境。

【讨论】:

  • 那么x[1,2]&lt;-7 是引用调用吗?
  • 不。这也将创造一个临时价值。大多数“常规 R”分配是按承诺调用的,这更像是按值调用而不是按引用调用。 data.table 包对其对象进行了适当的修改。 R6 机制旨在提供对对象的更直接访问并防止复制开销。
【解决方案2】:

由于`[`(x, y) 对对象进行切片,并且`&lt;-`(x, z) 执行赋值,因此`[&lt;-`(x,y,z) 似乎将执行赋值x[y] &lt;- y。 @42- 的回答很好地解释了 [&lt;- 的实际作用,而对 `levels<-`( What sorcery is this? 的最佳回答提供了一些关于 R 为何以这种方式工作的见解。

要查看 [&lt;- 的实际作用,您必须查看 C 源代码,[&lt;- 的源代码可以在 http://svn.r-project.org/R/trunk/src/main/subassign.c 找到(相关部分从第 1470 行开始)。您可以看到x,被“分配给”的对象受到保护,因此只有本地版本被变异。相反,我们使用 VectorAssign、MatrixAssign、ArrayAssign 等在本地执行赋值,然后返回结果。

【讨论】:

    猜你喜欢
    • 2020-08-17
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-01
    相关资源
    最近更新 更多