1 回答

TA貢獻1770條經驗 獲得超3個贊
Rstudio的行為
Rstudio的對象瀏覽器以一種強制修改后復制的方式修改它檢查的對象。具體來說,對象瀏覽器使用至少一個R函數,該函數在內部將對對象的調用強制進行評估,此過程將對象的命名字段的值從1 重置為2。從R-Internals手冊中:
當對象將要更改時,將查詢命名字段。值2表示在更改之前必須復制對象。[...]值1用于以下情況:原則上,在計算期間存在a的兩個副本,但不再存在,因此可以優化一些原始函數在這種情況下避免復制。
要查看對象瀏覽器修改了命名字段([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,...
一旦命名字段設置為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
R中[<-的可變行為
[<-wrt修改向量的行為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
- 1 回答
- 0 關注
- 565 瀏覽
添加回答
舉報