2016-04-01 19 views
2

同じ構造を持つ2つのdata.tableがあります。 2つのキー列の後に多数のデータ列が続きます。データ列の数はさまざまです。 2番目のdata.tableの値を最初のdata.tableの対応する行/列に追加したいとします。r data.table結合で複数の列を更新する

DT1 <- cbind(data.table(loc=c("L1","L2","L3"), product=c("P1","P2","P1")), matrix(10,nrow=3,ncol=12)) 
setkey(DT1, loc, product) 
DT1 
    loc product V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 
1: L1  P1 10 10 10 10 10 10 10 10 10 10 10 10 
2: L2  P2 10 10 10 10 10 10 10 10 10 10 10 10 
3: L3  P1 10 10 10 10 10 10 10 10 10 10 10 10 
DT2 <- cbind(data.table(loc=c("L2","L3"), product=c("P2","P1")), matrix(1:24,nrow=2,ncol=12)) 
setkey(DT2, loc, product) 
    loc product V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 
1: L2  P2 1 3 5 7 9 11 13 15 17 19 21 23 
2: L3  P1 2 4 6 8 10 12 14 16 18 20 22 24 

私の最善の策は、これまでnrowとNcoIおよびLOCと製品のエントリがソースデータに応じて、すべての変数であることを、次の

DT1[DT2, 3:14 := as.data.table(DT1[DT2, 3:14, with=FALSE] + DT2[, 3:14, with=FALSE]), with=FALSE] 
    loc product V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 
1: L1  P1 10 10 10 10 10 10 10 10 10 10 10 10 
2: L2  P2 11 13 15 17 19 21 23 25 27 29 31 33 
3: L3  P1 12 14 16 18 20 22 24 26 28 30 32 34 

注意です。

これはDT2のすべての行がDT1のものと一致する場合に機能しますが、それ以外の場合は予期しない結果が発生します。 DT1とDT2の両方を参照するこの可変数の列割り当てを行うために、RHSを表現するためのより厳密でエレガントな方法はありますか?

答えて

0

一つの可能​​性は、参加を行うことです、そしてあなたが列を重複している場合は、あなたは約合計

DT3 <- DT2[ DT1 ] 

dup <- names(DT3)[grep("[i.]", names(DT3))] 
dup2 <- gsub("[i.]", "", dup) 
expr <- paste0("`:=`(", paste0(dup2, "=", dup2, "+", dup, collapse = ","), ")") 

## set NA to 0 
for(j in names(DT3)) set(DT3, which(is.na(DT3[[j]])), j, 0) 

DT3[, eval(parse(text = expr))][, c("loc", "product", dup2), with=F] 

# loc product V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 
# 1: L1  P1 10 10 10 10 10 10 10 10 10 10 10 10 
# 2: L2  P2 11 13 15 17 19 21 23 25 27 29 31 33 
# 3: L3  P1 12 14 16 18 20 22 24 26 28 30 32 34 
5

方法を実行するために、これらの名前を使用するための式を作成することができます

cols = paste0('V', 1:12) 

DT1[DT2, (cols) := setDT(mget(cols)) + mget(paste0('i.', cols))] 
DT1 
# loc product V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 
#1: L1  P1 10 10 10 10 10 10 10 10 10 10 10 10 
#2: L2  P2 11 13 15 17 19 21 23 25 27 29 31 33 
#3: L3  P1 12 14 16 18 20 22 24 26 28 30 32 34 
+0

おかげで@ eddi。非常にエレガントなソリューション!私はsetDT関数に遭遇していなかった。 – sch56

+0

'paste0( 'i。'、'は実際には必要ありません。これはdata.tableで時間の経過とともに変更されましたか、それとも理解のために使用されましたか? – andrasz

+0

@andrasz必要がないと言ったらどういう意味なのでしょうか? 'i.'という接頭辞がなければ、' DT1'から列を追加するだけです。 – eddi

関連する問題