2017-04-07 54 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的速度。