`[<-` 函数在 R 中如何工作?
Posted
技术标签:
【中文标题】`[<-` 函数在 R 中如何工作?【英文标题】:How does the `[<-` function work in R? 【发布时间】:2016-05-10 10:24:33 【问题描述】:例如,我见过一些人使用 [<-
作为带有波兰符号的函数
x <- matrix(1:4, nrow = 2)
`[<-`(x, 1, 2, 7)
返回
[,1] [,2]
[1,] 1 7
[2,] 2 4
我已经尝试过使用 [<-
一点,看起来像这样使用它会打印类似 x[1,2] <- 7
的结果,而无需实际执行分配。但我无法确定这个函数实际上是做什么的,因为为?"["
提供的文档只是顺便提及它,我无法在谷歌或 SO 中搜索“[
是的,我知道实际上使用这可能是一个可怕的想法,我只是为了更好地理解R而感到好奇。
【问题讨论】:
这更像是 R 将x[1,2] <- 7
转换为 x <- '[<-'(x, 1, 2, 7)
。
如果你了解[
函数和<-
函数,那么[<-
函数就很有意义了。试试[(x,1,2)
。试试<-(a,1)
我没有看到这个重复。我认为的问题是为什么[<-
实际上不会影响符号/命名对象x
中的子赋值。这似乎不是提名副本中提出的问题。
"[<-"
是一个返回相应修改对象的函数。 "[<-"(x, i, value)
似乎就是这样做的。要查看显式 "[<-"
调用和 x[i] <- value
的解析方式之间的区别,也许可以参见 '*tmp*' = "tmp"; x = 1:3; x[2] <- 0; x; get("*tmp*")
VS '*tmp*' = "tmp"; x = 1:3; "[<-"(x, 2, 0); x; get("*tmp*")
,如 here 所述。
【参考方案1】:
这是你需要做的事情才能坚持下去:
`<-`( `[`( x, 1, 2), 7) # or x <- `[<-`( x, 1, 2, 7)
x
[,1] [,2]
[1,] 1 7
[2,] 2 4
基本上发生的事情是[
正在创建指向x
的行列位置的指针,然后是<-
(这实际上是assign
的同义词,也可以在中缀表示法中使用)正在做实际的“永久”任务。不要被误导认为这是一个引用调用分配。我有理由确定仍然会创建一个临时值 x
。
您的版本确实进行了子分配(从它返回的内容可以看出),但该分配仅在调用 [<-
的本地环境中,不包含全局环境。
【讨论】:
那么x[1,2]<-7
是引用调用吗?
不。这也将创造一个临时价值。大多数“常规 R”分配是按承诺调用的,这更像是按值调用而不是按引用调用。 data.table
包对其对象进行了适当的修改。 R6 机制旨在提供对对象的更直接访问并防止复制开销。【参考方案2】:
由于`[`(x, y)
对对象进行切片,并且`<-`(x, z)
执行赋值,因此`[<-`(x,y,z)
似乎将执行赋值x[y] <- y
。 @42- 的回答很好地解释了 [<-
的实际作用,而对 `levels<-`( What sorcery is this? 的最佳回答提供了一些关于 R 为何以这种方式工作的见解。
要查看 [<-
的实际作用,您必须查看 C 源代码,[<-
的源代码可以在 http://svn.r-project.org/R/trunk/src/main/subassign.c 找到(相关部分从第 1470 行开始)。您可以看到x
,被“分配给”的对象受到保护,因此只有本地版本被变异。相反,我们使用 VectorAssign、MatrixAssign、ArrayAssign 等在本地执行赋值,然后返回结果。
【讨论】:
以上是关于`[<-` 函数在 R 中如何工作?的主要内容,如果未能解决你的问题,请参考以下文章