2016-04-13 37 views
2

に2つの既存のデータフレームの列の間を選択する際の文の回避策「IF」私は、次のデータセットがあります。高速化R

x <- 1000 
df <- data.frame(a = sample(c("Jack", "Jill"), x, replace = TRUE), 
       b = sample(c("Bonnie", "Clyde"), x, replace = TRUE), 
       c = sample(c("blue", "green"), x, replace = TRUE)) 

を私はピックdf$adf$c == "blue"を選ぶのdf $選択肢と呼ばれる新しい列を作成したいとdf$c == "green"の場合はdf$bを選択します。 1000年わずか2秒である - X <がとき

choice <- function(y) { 
    nw1 <- df[y, ] 

    if(nw1$c == "blue") { 
    nw1$choice = nw1$a 
    } else { 
    nw1$choice <- nw1$b 
    } 

    print(nw1) 
} 

rows <- c(1:nrow(df)) 
df2 <- do.call("rbind", lapply(rows, function(y) choice(y))) 

経過時間のテスト:このような状況では、伝統的なififelse文と限界を理解

は、私が希望のタスクを実行するには、次の関数を作成しましたしかし、x < - 25000を膨らませると、経過時間は自分のマシンで60秒以上になります。

25000を超える行を処理するときにsystem.timeを短縮するために、このタスクについて別の方法を提案することはありますか?このトリックにはおそらく異なる適用機能がありますが、私はまだそれを理解していません。

+0

「ifelse」がベクトル化されている。 'if'はそうではないので、前者はRでもっと多く見ることができます。 – alistaire

+0

@rawrループを書くのではなく、いいえ?レベルの数が2つ以上の場合に意味を成す選択肢がありますが、それ以外の場合は「ifelse」は簡潔でうっすらです。 – alistaire

答えて

3

任意の関数のための必要はありませんか/ * applyループは、単に文字に要因を設定し、我々は非常に高速になり、単純なrow/columnインデックスを使用することができます

x <- 1000 
df <- data.frame(a = sample(c("Jack", "Jill"), x, replace = TRUE), 
       b = sample(c("Bonnie", "Clyde"), x, replace = TRUE), 
       c = sample(c("blue", "green"), x, replace = TRUE), stringsAsFactors = F) 


df$choice <- ifelse(df$c == "blue", df$a, df$b) 

head(df) 
    a  b  c choice 
1 Jack Bonnie blue Jack 
2 Jill Bonnie blue Jill 
3 Jack Clyde green Clyde 
4 Jack Bonnie green Bonnie 
5 Jill Bonnie green Bonnie 
6 Jill Bonnie blue Jill 
+0

ありがとう@Symbolix。私は明らかにstringsAsFactors = F部分を欠いていたので、私はifelseについて考えました。 – bshelt141

+0

@BrandonS - そうですね、これは一般的な「つかまえ」です! – SymbolixAU

2

新しい列に割り当てるためにifelseを使用

df$choice <- df[cbind(1:nrow(df),(df$c!="blue")+1L)] 
head(df) 
#  a  b  c choice 
#1 Jill Bonnie green Bonnie 
#2 Jill Clyde green Clyde 
#3 Jill Clyde green Clyde 
#4 Jill Clyde blue Jill 
#5 Jack Clyde blue Jack 
#6 Jack Clyde green Clyde