RStudio和R中的运算符“ [<-”

偶然地,我遇到了"[<-"操作员的奇怪行为。根据调用顺序以及我使用的是RStudio还是普通的RGui,它的行为有所不同。我将举一个例子来阐明自己。


x <- 1:10

"[<-"(x, 1, 111)

x[5] <- 123

据我所知,第一次分配不应该改变x(或者我错了?),而第二次应该改变。实际上,以上操作的结果是


x

[1]  1  2  3  4  123  6  7  8  9 10

但是,当我们以不同的顺序执行这些操作时,结果是不同的,x并且发生了变化!意思是:


x <- 1:10

x[5] <- 123

"[<-"(x, 1, 111)

x

[1] 111   2   3   4   123   6   7   8   9  10

但这只会在我使用普通R时发生!在RStudio中,两个选项的行为相同。我已经在两台机器上进行了检查(一台装有Fedora,一台装有Win7),情况看起来完全一样。我知道“功能性”版本("[<-"(x..))可能从未使用过,但我很好奇为什么会这样。谁能解释一下?


=========================


编辑:好的,所以从评论中我得到的原因是x <- 1:10类型为'integer'并在替换后x[5] <- 123为'double'。但是仍然有一个疑问,为什么RStudio中的行为会有所不同?我重新启动R会话,它没有任何改变。


慕沐林林
浏览 492回答 1
1回答

德玛西亚99

Rstudio的行为Rstudio的对象浏览器以一种强制修改后复制的方式修改它检查的对象。具体来说,对象浏览器使用至少一个R函数,该函数在内部将对对象的调用强制进行评估,此过程将对象的命名字段的值从1 重置为2。从R-Internals手册中:当对象将要更改时,将查询命名字段。值2表示在更改之前必须复制对象。[...]值1用于以下情况:原则上,在计算期间存在a的两个副本,但不再存在,因此可以优化一些原始函数在这种情况下避免复制。要查看对象浏览器修改了命名字段([NAM()]在下一个代码块中),请比较运行以下各行的结果。首先,两条“线”同时运行,因此Rstudio X在查询其结构之前没有时间“触摸” 。在第二个中,每行分别粘贴,因此X在检查之前先对其进行修改。## Pasted in togetherx <- 1:10; .Internal(inspect(x))# @46b47b8 13 INTSXP g0c4 [NAM(1)] (len=10, tl=0) 1,2,3,4,5,...## Pasted in with some delay between linesx <- 1:10.Internal(inspect(x))# @42111b8 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,...&nbsp;一旦命名字段设置为2,[<-(X, ...)将不会修改原始对象。一次将以下内容全部粘贴到Rstudio中会进行修改X,而逐行粘贴则不会:x <- 1:10"[<-"(x, 1, 111)所有这一切的另一个后果是,Rstudio的对象浏览器实际上使某些操作比原先的速度慢。再次比较相同的两个命令,首先将它们粘贴在一起,然后一次比较一个:## Pasted in togetherx <- 1:5e7system.time(x[1] <- 9L)#&nbsp; &nbsp; user&nbsp; system elapsed&nbsp;#&nbsp; &nbsp; &nbsp; &nbsp;0&nbsp; &nbsp; &nbsp; &nbsp;0&nbsp; &nbsp; &nbsp; &nbsp;0&nbsp;## Pasted in one at a timex <- 1:5e7system.time(x[1] <- 9L)#&nbsp; &nbsp; user&nbsp; system elapsed&nbsp;#&nbsp; &nbsp; 0.11&nbsp; &nbsp; 0.04&nbsp; &nbsp; 0.16&nbsp;R中[<-的可变行为[<-wrt修改向量的行为X取决于X为其分配元素的和的存储类型。这就解释了R的行为,而不是Rstudio的行为。在R中,当[<-要么追加到向量上X,要么执行需要X修改其类型的子分配时,将对其进行X复制,并且返回的值不会覆盖先前存在的变量X。(为此,您需要做类似的操作X <- "[<-(X, 2, 100)。因此,以下两个都不修改XX <- 1:2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;## Note: typeof(X) --> "integer"## Subassignment that requires that X be coerced to "numeric" type"[<-"(X, 2, 100) ## Note: typeof(100) --> "numeric"X&nbsp;# [1]&nbsp; &nbsp;1&nbsp; &nbsp;2## Appending to X"[<-"(X, 3, 100L)X# [1]&nbsp; &nbsp;1&nbsp; &nbsp;2但是,只要有可能,R都会允许该[<-函数X直接通过引用进行修改(即不进行复制)。这里的“可能”包括子分配不需要X修改的类型的情况。所以以下所有修改XX <- c(0i, 0i, 0i, 0i)"[<-"(X, 1, TRUE)"[<-"(X, 2, 20L)"[<-"(X, 3, 3.14)"[<-"(X, 4, 5+5i)X# [1]&nbsp; 1.00+0i 20.00+0i&nbsp; 3.14+0i&nbsp; 5.00+5i
打开App,查看更多内容
随时随地看视频慕课网APP