为什么更改列名需要花费很长时间才能使用大型data.frame?

时间:2012-06-14 17:45:28

标签: r dataframe data.table

我在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分钟让重命名完成,同时我去喝茶。我感兴趣的是发生了什么以及为什么?

1 个答案:

答案 0 :(得分:21)

正如一些评论者提到的那样,重命名数据框列很慢,因为(取决于你的工作方式)它会产生1到4个整个data.frame 的副本。在这里,从data.table的{​​{1}}帮助页面,展示我见过的这种行为是最好的方式:

?setkey

要(开始)理解为什么这样做的事情,你可能需要深入研究一些关于R-devel的相关讨论。以下是一对:R-devel: speeding up perceptionR-devel: Confused about NAMES

我对这些主题的印象主义解读是:

  1. 至少制作一份副本,以便在覆盖原件之前对其进行“试用”。因此,如果要重新分配的值有问题,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可以“退出”并发送错误消息,而不会对原始对象造成任何损害。

  2. R-core的几位成员对现在的工作方式并不完全满意。有几个人解释说在某些情况下“R失去了轨道”; Luke Tierney表示他过去曾尝试过对这种复制的一些修改“在少数情况下并且总是不得不退缩”;而Simon Urbanek暗示“也可能会有一些事情发生”

  3. (正如我所说,那只是印象派:我根本无法完全了解R的内部细节!)


    同样相关,如果你还没有看到它,这里有names<-“真正”有用的方式:

    names(z)[3] <- "c2"

    注意:大部分答案来自Matthew Dowle对this other question的回答。 (我认为值得把它放在这里,给它更多曝光,因为它与你自己的问题非常相关)。