我在R中有data.frame
,有1900万行和90列。我有足够的备用RAM和CPU周期。似乎在此数据框中更改单个列名称对于R来说是一个非常激烈的操作。
system.time(colnames(my.df)[1] <- "foo")
user system elapsed
356.88 16.54 373.39
为什么会这样?每行都以某种方式存储列名吗?这会创建一个全新的数据框吗?看来这个操作应该在微不足道的时间内完成。我在R manual entry中没有看到任何明显的内容。
我在Windows 7上运行R(64位)的7600版本,在我当前的工作区中,根据system.time()
在小型data.frame上设置colnames为'0'时间。
编辑:我知道使用data.table
的可能性,老实说,我可以等5分钟让重命名完成,同时我去喝茶。我感兴趣的是发生了什么以及为什么?
答案 0 :(得分:21)
正如一些评论者提到的那样,重命名数据框列很慢,因为(取决于你的工作方式)它会产生1到4个整个data.frame 的副本。在这里,从data.table
的{{1}}帮助页面,展示我见过的这种行为是最好的方式:
?setkey
要(开始)理解为什么这样做的事情,你可能需要深入研究一些关于R-devel的相关讨论。以下是一对:R-devel: speeding up perception和R-devel: Confused about NAMES
我对这些主题的印象主义解读是:
至少制作一份副本,以便在覆盖原件之前对其进行“试用”。因此,如果要重新分配的值有问题,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?
或[<-.data.frame
可以“退出”并发送错误消息,而不会对原始对象造成任何损害。
R-core的几位成员对现在的工作方式并不完全满意。有几个人解释说在某些情况下“R失去了轨道”; Luke Tierney表示他过去曾尝试过对这种复制的一些修改“在少数情况下并且总是不得不退缩”;而Simon Urbanek暗示“也可能会有一些事情发生”
(正如我所说,那只是印象派:我根本无法完全了解R的内部细节!)
同样相关,如果你还没有看到它,这里有names<-
“真正”有用的方式:
names(z)[3] <- "c2"
注意:大部分答案来自Matthew Dowle对this other question的回答。 (我认为值得把它放在这里,给它更多曝光,因为它与你自己的问题非常相关)。