2016-03-31 4 views
0

私は比較的頻繁に実行する必要がある基本的なタスクのパフォーマンスを向上させようとしています。for-loopをデータフレームに適用して置換する

 pair_id rr im db 
    1 A0A0B5JQ66_A0A0B5JFG2 NA yes NA 
    2 A0A024RA76_A0A024RA76 NA yes NA 
    3 A0A068F1B9_A0A068F1B9 NA yes NA 
    4 A0A098_A0A098 NA yes NA 
    5 A0A0B5JJY8_A0A0B5JFB4 yes NA NA 
    6 A0A0B5JK11_A0A0B5JK11 yes NA NA 
    7 A0A0B5JK74_A0A0B5JFG2 yes NA NA 
    8 A0A0B5JK74_A0A0B5JK74 yes NA NA 
    9 A0A0B5JKA2_A0A0B5JF96 NA yes NA 
    10 A0A0B5JKA2_A0A0B5JK74 NA yes NA 
    11 A0A0B5JPZ7_A0A0B5JFG2 yes yes NA 
    12 A0A0B5JPZ7_A0A0B5JK74 NA yes NA 
    13 A0A0B5JPZ7_A0A0B5JKA2 NA yes NA 
    14 A0A0B5JPZ7_A0A0B5JPZ7 NA yes NA 
    15 A0A0B5JQ10_A0A0B5JK95 yes yes NA 
    16 A0A0B5JQ14_A0A0B5JFB4 NA yes NA 
    17 A0A0B5JQ25_A0A0B5JFB4 NA yes NA 
    18 A0A0B5JQ25_A0A0B5JFB8 NA yes NA 
    19 A0A0B5JQ25_A0A0B5JK29 NA yes NA 
    20 A0A0B5JQ29_A0A0B5JQ14 yes NA NA 

私は列2及び3(「RR」と「イム」)を比較する必要がありますし、この比較に基づいて、列番号4の値を設定します。私はこのようになります。データフレーム「テスト」を持っています。このために、私は「比較」と呼ばれ、次の関数を作成している:それはちょうど、入力として二つの要素のベクトルをとり

compare <- function(v){ 
    if (v[1]=="yes" & is.na(v[2])){ 
    db <- "rr" 
    } 
    else if (v[2]=="yes" & is.na(v[1])){ 
    db <- "im" 
    } 
    else if (v[1]=="yes" & v[2]=="yes"){ 
    db <- "both" 
    } 
    else { 
    db <- "check" 
    } 
    db 
} 

を、1が「はい」の値を持っており、どちらが(もしあれば)空でチェック3番目の列に割り当てることができる値を返します。今

私が使用して「試験」でこれを使用しているため、ループ:

for (i in 1:nrow(test)){ 
     test[i,]$db <- compare(test[i,2:3]) 
} 

私のデータフレームが大きくなるように取得するときに、このソリューションは、(私が700000を超えるといくつかを管理する必要が非常に非効率的です行)、計算に多くの時間がかかります。私は 'apply'ファミリーのさまざまな変種の下で自分の関数を使用しようとしていましたが、Rには新しく、この一連の関数で多くの経験を持っていないので、動作させることができませんでした。優先順位を向上させる代替手段に関するヒント?

答えて

0

あなたがしたいことにするだろうあなたは、関数に

test$db <- apply(test[, 2:3], compare) 

を適用し使用することができますが、これは

はるかに高速ではありませんこれを試して。それはあなたにパフォーマンスの向上を与えるはずです。答えを与えたすべての人に

library(dplyr) test <- mutate(test, db = ifelse(rr == "yes" & is.na(im), "rr", ifelse(is.na(rr) & im == "yes", "im", ifelse(rr == "yes" & im == "yes", "both", "check"))))

2

速く解決策は、ベクトル化の使用が

test$db <- "check" #make column of default values 
test$db[test$rr == "yes" & is.na(test$im)] <- "rr" 
test$db[test$im == "yes" & is.na(test$rr)] <- "im" 
test$db[test$rr == "yes" & test$im == "yes"] <- "both" 
0

感謝。実際には、10000行のテストデータフレームを使って、オリジナルのfor-loopで提案されたさまざまなアプローチを試して比較しました。ここに私が持っているものがあります:

    user system elapsed 
    ptm_loop  4.831 0.551 5.390 
    ptm_apply  0.055 0.002 0.056 
    ptm_vect  0.046 0.001 0.046 
    ptm_dplyr  0.009 0.000 0.009 

ptmは処理時間が短く、それぞれの解決策は略語で示されています。それらのすべてがパフォーマンスを大幅に向上させますが、これまでのところ最も速い解決策は、Psidomが作成したdplyrベースの提案です。

関連する問題