1 回答

TA貢獻(xiàn)1770條經(jīng)驗(yàn) 獲得超3個(gè)贊
Rstudio的行為
Rstudio的對象瀏覽器以一種強(qiáng)制修改后復(fù)制的方式修改它檢查的對象。具體來說,對象瀏覽器使用至少一個(gè)R函數(shù),該函數(shù)在內(nèi)部將對對象的調(diào)用強(qiáng)制進(jìn)行評估,此過程將對象的命名字段的值從1 重置為2。從R-Internals手冊中:
當(dāng)對象將要更改時(shí),將查詢命名字段。值2表示在更改之前必須復(fù)制對象。[...]值1用于以下情況:原則上,在計(jì)算期間存在a的兩個(gè)副本,但不再存在,因此可以優(yōu)化一些原始函數(shù)在這種情況下避免復(fù)制。
要查看對象瀏覽器修改了命名字段([NAM()]在下一個(gè)代碼塊中),請比較運(yùn)行以下各行的結(jié)果。首先,兩條“線”同時(shí)運(yùn)行,因此Rstudio X在查詢其結(jié)構(gòu)之前沒有時(shí)間“觸摸” 。在第二個(gè)中,每行分別粘貼,因此X在檢查之前先對其進(jìn)行修改。
## 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,...
一旦命名字段設(shè)置為2,[<-(X, ...)將不會修改原始對象。一次將以下內(nèi)容全部粘貼到Rstudio中會進(jìn)行修改X,而逐行粘貼則不會:
x <- 1:10
"[<-"(x, 1, 111)
所有這一切的另一個(gè)后果是,Rstudio的對象瀏覽器實(shí)際上使某些操作比原先的速度慢。再次比較相同的兩個(gè)命令,首先將它們粘貼在一起,然后一次比較一個(gè):
## 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中[<-的可變行為
[<-wrt修改向量的行為X取決于X為其分配元素的和的存儲類型。這就解釋了R的行為,而不是Rstudio的行為。
在R中,當(dāng)[<-要么追加到向量上X,要么執(zhí)行需要X修改其類型的子分配時(shí),將對其進(jìn)行X復(fù)制,并且返回的值不會覆蓋先前存在的變量X。(為此,您需要做類似的操作X <- "[<-(X, 2, 100)。
因此,以下兩個(gè)都不修改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都會允許該[<-函數(shù)X直接通過引用進(jìn)行修改(即不進(jìn)行復(fù)制)。這里的“可能”包括子分配不需要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
- 1 回答
- 0 關(guān)注
- 570 瀏覽
添加回答
舉報(bào)