2017-04-07 58 views
2

d是预先分配的大矩阵从一个小data.frame将数据复制到一个更大的data.frame

d = as.data.frame(matrix(NA,ncol=3,nrow=5e7)) 
names(d) = c("x","y","z") 

dsub是相同的列数和相同的列名作为小矩阵d

dsub = data.frame(x = 1:4,y=1:4,z=1:4) 

我想数据从dsub在线复制到d 5-8

d[5:8,] = dsub 

此操作非常慢。看来R正在复制整个data.frame d

  • 这是为什么?

  • 如何让这个过程更快?

+1

是......弗吉尼亚... R正在复制整个数据帧。这就是R的工作原理。这可能比你想象的还要糟糕。它可能会多次复制它。 data.table包是为了解决这个问题而设计的。 –

回答

2

this commentdata.table包提到与修改只有几行复制时整个对象来克服这个问题。

证明效果的最好方法是基准。因此,data.table包提供的不同方法可以进行比较。

设置数据

df <- as.data.frame(matrix(NA_integer_, ncol = 3, nrow = 5e7)) 
names(df) = c("x", "y", "z") 
dt <- setDT(copy(df)) 
dsub <- data.frame(x = 1:4, y = 1:4, z = 1:4) 

注意,目标对象与NA_integer_代替NAlogical类型的初始化。这样可以避免将左手强制转换为整数(以及由data.table发出的相应警告)所导致的开销。

标杆
mb <- microbenchmark::microbenchmark(
    df = d[5:8,] <- dsub, 
    dt1 = dt[5:8] <- dsub, 
    dt2 = dt[5:8, (c("x","y","z")) := .SD], 
    dt3 = set(dt, 5:8, 1:3, dsub), 
    times = 10, 
    unit = "ms" 
) 

print(mb, unit = "relative") 
#Unit: relative 
# expr  min   lq  mean  median   uq   max neval cld 
# df 56458.1921 27397.98069 27932.40685 29796.52860 34413.21160 29487.64751 10 b 
# dt1 49142.9608 24959.42180 22909.58526 20687.62826 30129.96416 21349.51295 10 b 
# dt2 111.9582 86.57717 54.36988 70.89935 69.36287 31.89704 10 a 
# dt3  1.0000  1.00000  1.00000  1.00000  1.00000  1.00000 10 a 

注意,基准测试结果是相对于它是data.tableset()功能最快方法印刷。然而,使用常规data.table systax(案例dt2)通过引用进行更新的速度大于data.frame的速度。