gpt4 book ai didi

r - RStudio 和 R 中的运算符 "[<-"

转载 作者:行者123 更新时间:2023-12-03 04:58:11 25 4
gpt4 key购买 nike

偶然我遇到了 "[<-" 的奇怪行为运算符(operator)。它的行为有所不同,具体取决于调用顺序以及我使用的是 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类型为“整数”,替换 x[5] <- 123 后这是“双重”。但仍然存在一个问题,为什么 RStudio 中的行为有所不同?我重新启动 R session ,但它没有改变任何内容。

最佳答案

Rstudio 的行为

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

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在检查之前进行修改。

## 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 ,而逐行粘贴则不会:

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

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

## 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
<小时/>

[<- in R

的可变行为

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

在 R 中,当 [<-要么附加到向量 X ,或执行需要 X 的子分配的类型被修改,X被复制并且返回的值不会覆盖预先存在的变量 X 。 (为此,您需要执行类似 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的情况。的类型被修改。

因此以下所有内容都会修改 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

关于r - RStudio 和 R 中的运算符 "[<-",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43412974/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com