在R中更新数据集的最快方法是什么?

时间:2016-11-02 08:09:17

标签: r performance dataframe data.table

我有一个20000 * 5的数据集。目前,它正在以迭代方式处理,并且数据集在每次迭代时都会不断更新。

data.frame中的单元格会针对每次迭代进行更新,并在更快地运行这些内容时寻求帮助。由于这是一个小的data.frame,我不确定data.table是否可以正常工作。

以下是data.frame子分配的基准:

sessionInfo()
R version 3.2.4 Revised (2016-03-16 r70336)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows Server >= 2012 x64 (build 9200)
set.seed(1234)
test <- data.frame(A = rep(LETTERS  , 800), B = rep(1:26, 800),    C=runif(20800), D=runif(20800) , E =rnorm(20800))
microbenchmark::microbenchmark(test[765,"C"] <- test[765,"C"] + 25)
Unit: microseconds
                                  expr     min       lq     mean   median       uq      max neval
 test[765, "C"] <- test[765, "C"] + 25 112.306 130.8485 979.4584 186.3025 197.7565 44556.15   100}

有没有办法比我发布的更快地实现上述功能?

2 个答案:

答案 0 :(得分:4)

有趣的是,如果你正在使用data.table,乍看之下似乎并不快。也许在循环中使用赋值时速度会变快。

library(data.table)
library(microbenchmark)
dt <- data.table(test)

# Accessing the entry
dt[765, "C", with = FALSE] 

# Replacing the value with the new one
# Basic data.table syntax
dt[i =765, C := C + 25 ]

# Replacing the value with the new one
# using set() from data.table
set(dt, i = 765L, j = "C", value = dt[765L,C] + 25)

microbenchmark(
      a = set(dt, i = 765L, j = "C", value = dt[765L,C] + 25)
    , b = dt[i =765, C := C + 25 ]
    , c = test[765, "C"] <- test[765, "C"] + 25
    , times = 1000       
  )

microbenchmark的结果:

                                                   expr     min      lq     mean  median       uq      max neval
 a = set(dt, i = 765L, j = "C", value = dt[765L, C] + 25) 236.357 46.621 266.4188 250.847 260.2050  572.630  1000
 b = dt[i = 765, `:=`(C, C + 25)]                         333.556 345.329 375.8690 351.668 362.6860 1603.482  1000
 c = test[765, "C"] <- test[765, "C"] + 25                73.051  81.805 129.1665  84.220  87.6915 1749.281  1000

答案 1 :(得分:2)

您可以从?set功能的手册开始。在示例中,您将找到可用于基准测试的代码。我只是重新运行它并得到以下时间。

library(data.table)
m = matrix(1, nrow = 2e6L, ncol = 100L)
DF = as.data.frame(m)
DT = as.data.table(m)    

system.time(for (i in 1:1000) DF[i, 1] = i)
#   user  system elapsed 
#  3.048   1.512  24.854
system.time(for (i in 1:1000) DT[i, V1 := i])
#   user  system elapsed 
#  0.232   0.000   0.259 
system.time(for (i in 1:1000) set(DT, i, 1L, i))
#   user  system elapsed 
#  0.000   0.000   0.002

理想情况下,您需要检查数据的数据更新方案并进行扩展,以正确衡量哪个是“最快”的。另外一定要检查内存使用情况,使用矩阵上的[<-似乎比data.table方式使用更多内存,如果最终交换速度会慢一些。