2013-04-24 74 views
4

我有一個數據框,我想添加另一列,這是涉及3個其他列的計算結果。我現在使用的方法似乎很慢。有沒有更好的方法來做同樣的事情?這是我正在使用的方法。R:在數據幀的多列上執行行計算的最快方法

library(bitops) 

GetRes<-function(A, B, C){ 
    tagU <- bitShiftR((A*C), 4) 
    tagV <- bitShiftR(B, 2) 

    x<-tagU %% 2 
    y<-tagV %% 4 

    res<-(2*x + y) %% 4 
    return(res) 
} 

df <- data.frame(id=letters[1:3],val0=1:3,val1=4:6,val2=7:9) 
apply(df, 1, function(x) GetRes(x[2], x[3], x[4])) 

我的數據幀非常大,並且需要很長時間才能完成此計算。有人建議我做得更好嗎?

謝謝。

回答

3

一切比你就可以選擇任何其他替代快得多。你可以叫這個...

with(df, GetRes(val0, val1, val2)) 

或本

GetRes(df$val0, df$val1, df$val2) 

或本

GetRes(df[,2], df[,3], df[,4]) 
+1

+1,我不知道bitShiftL是矢量化函數 – 2013-04-24 06:54:24

7

嘗試mapply

mapply(GetRes, df[,2], df[,3], df[,4]) 

如果你讓我們知道這包bitShiftR是,我們可以測試它在更大的數據,看看是否有任何性能提升。

UPDATE
快速基準測試顯示,mapply是快兩倍,你正在做的是已經矢量化的apply

microbenchmark(apply(df[,2:4], 1, function(x) GetRes(x[1], x[2], x[3])), mapply(GetRes, df[,2], df[,3], df[,4])) 
Unit: microseconds 
                 expr  min  lq median  uq  max neval 
apply(df[, 2:4], 1, function(x) GetRes(x[1], x[2], x[3])) 196.985 201.6200 206.7515 216.187 1006.775 100 
       mapply(GetRes, df[, 2], df[, 3], df[, 4]) 99.982 105.6105 108.7560 112.232 149.311 100 
+0

增加。它來自'bitops' – 2013-04-24 05:53:15

+1

如果'mapply'工作得更快,也可能使用它的並行版本:'library(parallel); mcapply(GetRes,df [,2],df [,3],df [,4],mc.cores = xxx)',其中'xxx'是計算機中的核心數量。 – 2013-04-24 06:45:14