2017-10-12 12 views
0

私は単純化されたデータ・フレーム1(DF1)がある場合に複数の出力を作成するには条件のセットを比較し、ELSEステートメント

set.seed(100) 
df1 = data.frame(greater_than_or_equal_to= unique(cummax(sample.int(100)))) 
df1$less_than = c(df1$greater_than_or_equal_to[2:nrow(df1)], 
        df1$greater_than_or_equal_to[nrow(df1)]+3) 
df1$score1 = round(runif(10,1,10),1) 
df1$score2 = round(runif(10,2,20),1) 
df1 = df1[1:5,] 

df1 
greater_than_or_equal_to less_than score1 score2 
        31  55 3.9 17.1 
        55  77 4.5 16.5 
        77  79 1.4 3.5 
        79  93 4.3 6.3 
        93  94 6.1 19.4 

私は別の簡略化されたデータ・フレーム(DF2)を有する:

df2 = data.frame(benchmark = runif(5,31,94)) 
df2 = round(df2,1) 
df2 
benchmark 
    50.4 
    47.2 
    65.8 
    34.6 
    60.5 

df2のベンチマークとdf1の最初の2つの列の範囲を比較し、df1のscore1とscore2を使用してdf2に複数の新しい列を作成します。

サンプルコードと出力:

for (i in 1:nrow(df2)){ 
    if (df2$benchmark[i] < 55) { 
    df2$cav[i] = df1$score1[1] 
    df2$gold[i] = df1$score2[1] 
    } else if (df2$benchmark[i] < 77) { 
    df2$cav[i] = df1$score1[2] 
    df2$gold[i] = df1$score2[2] 
    } else if (df2$benchmark[i] < 79) { 
    df2$cav[i] = df1$score1[3] 
    df2$gold[i] = df1$score2[3] 
    } else if (df2$benchmark[i] < 93) { 
    df2$cav[i] = df1$score1[4] 
    df2$gold[i] = df1$score2[4] 
    } else { 
    df2$cav[i] = df1$score1[5] 
    df2$gold[i] = df1$score2[5] 
    } 
} 

df2 
benchmark gold cav 
    50.4 17.1 3.9 
    47.2 17.1 3.9 
    65.8 16.5 4.5 
    34.6 17.1 3.9 
    60.5 16.5 4.5 

このコードは、私が欲しかったものを生成しますが、DF1とDF2が一致するように、1000行を言っている場合、それは効率的ではありません。どのように私はこのプロセスを効率的に拡大することができますか?

ありがとうございます!

答えて

1

作業している列がソートされていることを確認して、ループ戦略を少し変えていくことで、いくらか利益を得ることができます。ここにはそれぞれ5000行のコードがあります。それは数秒で実行されますが、通常はほとんどの人にとって十分です。

set.seed(100) 
df1 = data.frame(greater_than_or_equal_to= sort(runif(5000, 5, 1500))) 
df1$less_than = c(df1$greater_than_or_equal_to[2:nrow(df1)], 
        df1$greater_than_or_equal_to[nrow(df1)]+3) 
df1$score1 = round(runif(5000,1,10),1) 
df1$score2 = round(runif(5000,2,20),1) 
df1 = df1[1:5000,] 

df2 = data.frame(benchmark = runif(5000,1,940)) 
df2 = round(df2,1) 

ここに新しいループがあります。

#init the new columns 
df2$cav<-NA 
df2$gold<-NA 

#sort the cols we need to be sorted 
df1<-df1[order(df1$less_than),] 
df2<-df2[order(df2$benchmark),] 

#loop through df1 and fill in the corresponding values 
for(i in 1:nrow(df1)){ 
    val<-df1[i,]$less_than 
    rows<-which(is.na(df2$cav) & df2$benchmark < val) 

    #might not be any matches 
    if(length(rows) > 0){ 
    df2[rows,]$cav<-df1[i,]$score1 
    df2[rows,]$gold<-df1[i,]$score2 
    } 

    #we can stop when it is full 
    if(all(!is.na(df2))){ 
    break 
    } 
} 
関連する問題