运算符“[<-";在 RStudio 和 R [英] Operator &quot;[&lt;-&quot; in RStudio and R

查看:57
本文介绍了运算符“[<-";在 RStudio 和 R的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

偶然地,我遇到了 "[<-" 运算符的奇怪行为.它的行为取决于调用顺序以及我使用的是 RStudio 还是普通的 RGui.我会用一个例子来说明.

By accident i've encountered strange behaviour of "[<-" operator. It behaves differently depending on order of calls and whether i'm using RStudio or just ordinary RGui. I will make myself clear with an example.

x <- 1:10
"[<-"(x, 1, 111)
x[5] <- 123

据我所知,第一个赋值不应该改变 x(或者我错了?),而第二个应该改变.而实际上上述操作的结果是

As far as i know, first assigment shouldn't change x (or maybe i'm wrong?), while the second should do. And in fact the result of above operations is

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

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

However, when we perform these operations in different order, results are different and x has changed! Meaningly:

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..)) 可能从未使用过,但我很好奇为什么会发生这种情况.有人能解释一下吗?

But it only happens when i'm using plain R! In RStudio the behaviour is the same in both options. I've checked it on two machines (one with Fedora one with Win7) and the situation looks exactly the same. I know the 'functional' version ("[<-"(x..)) is probably never used but i'm very curious why it is happening. Could anyone explain that?

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

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

好的,所以从评论中我知道原因是 x <- 1:10 的类型是整数",并且在替换 x[5] <- 123 之后它是'双倍的'.但仍然存在问题,为什么 RStudio 中的行为不同?我重新启动了 R 会话,它没有改变任何东西.

Ok, so from comments i get that the reason was that x <- 1:10 has type 'integer' and after replacing x[5] <- 123 it's 'double'. But still remains question why behaviour is different in RStudio? I restart R session and it doesn't change anything.

推荐答案

Rstudio 的行为

Rstudio 的对象浏览器以一种在修改时强制复制的方式修改它检查的对象.具体来说,对象浏览器使用至少一个 R 函数,其调用在内部强制对对象进行评估,在此过程中将对象的 named 字段的值从 1 重置为 2.来自 R-Internals 手册:

Rstudio's behavior

Rstudio's object browser modifies objects it examines in a way that forces copying upon modification. Specifically, the object browser employs at least one R function whose call internally forces evaluation of the object, in the process resetting the value of the object's named field from 1 to 2. From the R-Internals manual:

当一个对象即将被改变时,会查询命名字段.值为 2 表示在更改对象之前必须复制该对象.[...] 值 1 用于以下情况 [...] 原则上在计算期间存在两个 a 副本 [...] 但不再存在,因此可以优化一些原始函数在这种情况下避免复制.

When an object is about to be altered, the named field is consulted. A value of 2 means that the object must be duplicated before being changed. [...] A value of 1 is used for situations [...] where in principle two copies of a exist for the duration of the computation [...] but for no longer, and so some primitive functions can be optimized to avoid a copy in this case.

要查看对象浏览器修改了named 字段(下一个代码块中的[NAM()]),请比较运行以下几行的结果.首先,两条行"一起运行,因此 Rstudio 在查询其结构之前没有时间触摸"X.第二种,每一行是单独粘贴的,所以X在检查之前被修改.

To see that the object browser modifies the named field ([NAM()] in the next code block), compare the results of running the following lines. In the first, both 'lines' are run together, so that Rstudio has no time to 'touch' X before its structure is queried. In the second, each line is pasted in separately, so X is modified before it is examined.

## Pasted in together
x <- 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 lines
x <- 1:10
.Internal(inspect(x))
# @42111b8 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,... 

一旦 named 字段设置为 2,[<-(X, ...) 将不会修改原始对象.将以下内容一次性粘贴到 Rstudio 中会修改 X,而逐行粘贴则不会:

Once the named field is set to 2, [<-(X, ...) will not modify the original object. Pasting the following into Rstudio all at once modifies X, while pasting it in line-by-line does not:

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

所有这一切的另一个后果是,Rstudio 的对象浏览器实际上使某些操作比原本更慢.再次比较首先粘贴在一起的相同的两个命令,然后一次一个:

One more consequence of all this is that Rstudio's object browser actually makes some operations slower than they would otherwise be. Again, compare the same two commands first pasted in together, and then one at a time:

## Pasted in together
x <- 1:5e7
system.time(x[1] <- 9L)
#    user  system elapsed 
#       0       0       0 

## Pasted in one at a time
x <- 1:5e7
system.time(x[1] <- 9L)
#    user  system elapsed 
#    0.11    0.04    0.16 

<小时>

[<- 在 R

中的变量行为

[<- 的行为 w.r.t.修改向量 X 取决于 X 的存储类型以及分配给它的元素的存储类型.这解释了 R 的行为,而不是 Rstudio 的行为.


Variable behavior of [<- in R

The behavior of [<- w.r.t. modifying a vector X depends on the storage types of X and of the element being assigned into it. This explains R's behavior but not Rstudio's.

在 R 中,当 [<- 附加到向量 X 或执行需要 X 类型的子赋值时被修改,X 被复制并且返回的值不会覆盖预先存在的变量X.(要做到这一点,您需要执行类似 X <- "[<-(X, 2, 100).

In R, when [<- either appends to a vector X, or performs a subassignment that requires that X's type be modified, X is copied and the value that is returned does not overwrite the pre-existing variable X. (To do that you need to do something like X <- "[<-(X, 2, 100).

所以,以下都不修改X

X <- 1:2         ## Note: typeof(X) --> "integer"

## Subassignment that requires that X be coerced to "numeric" type
"[<-"(X, 2, 100) ## Note: typeof(100) --> "numeric"
X 
# [1]   1   2

## Appending to X
"[<-"(X, 3, 100L)
X
# [1]   1   2

不过,R 确实允许 [<- 函数通过引用直接修改 X(即,无需复制).这里的可能"包括子赋值不需要修改 X 类型的情况.

Whenever possible, though, R does allow the [<- function to modify X directly by reference (i.e. without making a copy). "Possible" here includes cases in which a sub-assignment doesn't require that X's type be modified.

所以以下所有修改X

X <- c(0i, 0i, 0i, 0i)
"[<-"(X, 1, TRUE)
"[<-"(X, 2, 20L)
"[<-"(X, 3, 3.14)
"[<-"(X, 4, 5+5i)
X
# [1]  1.00+0i 20.00+0i  3.14+0i  5.00+5i

这篇关于运算符“[<-";在 RStudio 和 R的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆