2013-04-24 4 views
4

다른 세 열을 포함하는 계산 결과 인 다른 열을 추가하려는 데이터 프레임이 있습니다. 내가 지금 사용하고있는 방법은 매우 느린 것 같습니다. 같은 작업을 수행하는 더 좋은 방법이 있습니까? 여기에 제가 사용하는 접근법이 있습니다.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이 벡터화 된 함수라는 것을 몰랐다. –

7

은 우리가 어떤 성능 향상이 있는지 확인하기 위해 더 큰 데이터를 테스트 할 수 있습니다,

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

당신은 우리로부터 어떤 패키지 bitShiftR 알려 경우 mapply을보십시오.

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'에서 나온 것입니다. –

+1

'mapply'가 더 빨리 작동한다면 병렬 버전을 사용할 가치가 있습니다 :'library (parallel); mcapply (GetRes, df [, 2], df [, 3], df [, 4], mc.cores = xxx)', 여기서 xxx는 컴퓨터의 코어 크기입니다. –

관련 문제