正如几位评论者所提到的,重命名数据框列很慢,因为(取决于您如何操作)它会复制整个 data.frame的 1 到 4 个副本。在这里,来自data.table
的?setkey
帮助页面,是我见过的展示这种行为的最佳方式:
DF = data.frame(a=1:2,b=3:4) # base data.frame to demo copies
try(tracemem(DF)) # try() for non-Windows where R is
# faster without memory profiling
colnames(DF)[1] <- "A" # 4 copies of entire object
names(DF)[1] <- "A" # 3 copies of entire object
names(DF) <- c("A", "b") # 1 copy of entire object
`names<-`(DF,c("A","b")) # 1 copy of entire object
x=`names<-`(DF,c("A","b")) # still 1 copy (so not print method)
# What if DF is large, say 10GB in RAM. Copy 10GB just to change a column name?
要(开始)理解为什么会这样做,您可能需要深入研究 R-devel 上的一些相关讨论。这里有几个:R-devel:加速感知和R-devel:对 NAMES 感到困惑
我对这些线程的印象派解读是:
至少制作一份副本,以便在覆盖原件之前可以“尝试”对其进行修改。因此,如果要重新分配的值有问题,[<-.data.frame
或者names<-
可以“退出”并传递错误消息,而不会对原始对象造成任何损害。
R-core 的几个成员对现在的情况并不完全满意。一些人解释说,在某些情况下“R 迷失了方向”;卢克·蒂尔尼(Luke Tierney)表示,他过去“在少数情况下曾尝试过与此复制有关的一些修改,但总是不得不退缩”;西蒙厄巴内克暗示“也可能会有一些事情发生”
(不过,正如我所说,这只是印象派:我根本无法完整了解 R 的内部细节!)
同样相关的是,如果您还没有看到它,以下是names(z)[3] <- "c2"
“真正”之类的工作原理:
# From ?names<-
z <- "names<-"(z, "[<-"(names(z), 3, "c2"))
注意:这个答案大部分来自 Matthew Dowle 对this other question的回答。(我认为值得将它放在这里,并给它更多的曝光,因为它与您自己的问题非常相关)。