2017-03-21 6 views
0

data.tabledtに新しい列を作成する必要があります。この列には、data.framedfのデータが含まれます。次のように私のデータは次のとおりです。R内のdata.tableの代入で比較を使用

library(data.table) 
df <- data.frame(letter = LETTERS[1:9], number = 1:9) 
dt <- data.table(value = c(0.5, 2.5, 6, 8.5, 4.5, 1.6, 1.3, 7.8, 9.2)) 

、私はnumberの最小より大きいまたは等しい値に対応するdfからletterが含まれていますvalueの値に基づいてdtcolと呼ばれる新しい列を作成したいですvalueより。例を与えるために、カラムcolの最初の行はdtの最初の行に、1のでA(つまりAに対応dfからnumberカラムである)最小値よりも大きいか、0.5に等しいvalueを含むべきです。私は次のコードを試しました:

dt[, col := df[which(value <= df[, 2])[1], 1]] 

しかし、それはすべての行にAを置きます。 A、C、F、I、E、B、B、H、およびNAの所望の出力を生成

setDF(dt) 
for(i in 1:nrow(dt)) { 
dt$col[i] <- as.character(df[which(dt$value[i] <= df[, 2])[1], 1]) 
} 

を次のように私はこれはdata.frame有する可能性。 data.tableでどうすればいいですか?

+0

@Frank:野生の推測: 'df'は' data.frame() 'によって作成され、' letters'を 'factor'に強制するためです。 – Uwe

+1

はい、そうです。私はこの例を修正した。 – Skumin

+0

これは、 'dt [i、" col "] <-'に変更するとうまくいきます。 – Frank

答えて

0

ローリングジョインでこれを行うことができます。 verboseを使用し、より簡単にこのような問題(整数とダブルをマージ)をキャッチする

setDT(df) 
df[, number := as.numeric(number)] 

dt[, v := df[.SD, on=.(number = value), roll=-Inf, letter]] 


    value col v 
1: 0.5 A A 
2: 2.5 C C 
3: 6.0 F F 
4: 8.5 I I 
5: 4.5 E E 
6: 1.6 B B 
7: 1.3 B B 
8: 7.8 H H 
9: 9.2 NA NA 

:しかし、numbervalueは、両方の最初の同じタイプである必要があります

# when number is still an int... 
df[dt, on=.(number = value), roll=-Inf, verbose=TRUE] 


Calculated ad hoc index in 0 secs 
Coercing double column i.'value' to integer to match type of x.'number'. Please avoid coercion for efficiency. 
Starting bmerge ...done in 0 secs 
    letter number 
1:  A  0 
2:  B  2 
3:  F  6 
4:  H  8 
5:  D  4 
6:  A  1 
7:  A  1 
8:  G  7 
9:  I  9 

あなたが設定することができますoptions(datatable.verbose = TRUE)との完全なRセッションの詳細な冗長性。

+0

これは動作します、ありがとうございます。 'data.table'には、一度に1つの値しか取られず、列全体ではなく指定されるべき方法を指定する方法はありませんか?私は元の投稿の振る舞いは、 'dt [、col:= df [value(= df [、2])[1]、1]]'の 'value'が列全体これはリサイクルされて0.5しか含まれないため、 'col'全体にAが入ります。 – Skumin

+0

@Skumin申し訳ありませんが、私はその質問を理解するとは思わない。私はdata.frameとdata.tableの構文とオブジェクトを混合していたので、あなたのOPのアプローチは難しいと感じました。 – Frank

関連する問題