最簡單/最清楚的事在將新列轉換爲矩陣(以便設置列名稱)後,將原始對象與新列合併。
set.seed(21)
newData <- rnorm(n)
x1 <- merge(x, matrix(newData, ncol=1, dimnames=list(NULL, new.col.name)))
# another way to do the same thing
dim(newData) <- c(nrow(x), 1)
colnames(newData) <- new.col.name
x2 <- merge(x, newData)
要回答你的第二個問題:是的,一個XTS對象分配名稱(和colnames)創建一個副本。您可以通過使用tracemem
和gc
的輸出來查看它。
> R -q # new R session
R> x <- xts::.xts(1:1e6, 1:1e6)
R> tracemem(x)
[1] "<0x2892400>"
R> gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 259260 13.9 592000 31.7 350000 18.7
Vcells 1445207 11.1 4403055 33.6 3445276 26.3
R> colnames(x) <- "hi"
tracemem[0x2892400 -> 0x24c1ad0]:
tracemem[0x24c1ad0 -> 0x2c62d30]: colnames<-
tracemem[0x2c62d30 -> 0x3033660]: dimnames<-.xts dimnames<- colnames<-
tracemem[0x3033660 -> 0x3403f90]: dimnames<-.xts dimnames<- colnames<-
tracemem[0x3403f90 -> 0x37d48c0]: colnames<- dimnames<-.xts dimnames<- colnames<-
tracemem[0x37d48c0 -> 0x3033660]: dimnames<-.xts dimnames<- colnames<-
R> gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 259696 13.9 592000 31.7 350000 18.7
Vcells 1445750 11.1 4403055 33.6 3949359 30.2
R> print(object.size(x), units="Mb")
7.6 Mb
你可以看到colnames<-
調用導致使用的額外內存4MB〜(以下簡稱「使用(MB)最大」增加的量)。整個xts對象是〜8MB,其中一半是coredata
,另一半是index
。所以使用4MB的額外內存是複製coredata
。
如果您想避免複製,可以手動設置。但要小心,因爲你可以做一些其他事情,否則會被colnames<-.xts
中的「檢查」所捕獲。
> R -q # new R session
R> x <- xts::.xts(1:1e6, 1:1e6)
R> tracemem(x)
[1] "<0x2cc5330>"
R> gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 256397 13.7 592000 31.7 350000 18.7
Vcells 1440915 11.0 4397699 33.6 3441761 26.3
R> attr(x, 'dimnames') <- list(NULL, "hi")
tracemem[0x2cc5330 -> 0x28f4a00]:
R> gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 256403 13.7 592000 31.7 350000 18.7
Vcells 1440916 11.0 4397699 33.6 3441761 26.3
R> print(object.size(x), units="Mb")
7.6 Mb
正如我在我的回答中所說的,設置'colnames'確實會創建副本。例如:'x < - .xts(1,1); tracemem(X); colnames(x)< - 「hi」' –
我正在編輯,而你添加了那條評論@JoshuaUlrich實際的矩陣數據是不是被複制的呢? –
實際的矩陣數據很難被複制。我已經在我的答案中添加了一些細節來演示。 –