2016-04-01 25 views
2

içinde birden çok sütun güncelleştirin Aynı yapıya sahip iki data.table var. İki anahtar sütun ve ardından bir dizi veri sütunu. Veri sütunlarının sayısı değişebilir. İkinci data.table değerlerini ilk data.table içindeki karşılık gelen satırlara/sütunlara eklemek istiyorum.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 

Benim iyi bahis bugüne kadar sat_say ve Ncol ve loc ve ürün girişleri kaynak verilere bağlı olarak tüm değişkendir aşağıdaki

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 

Not olduğunu.

Bu, DT2'deki her satır bir DT1 ile eşleşiyorsa çalışır, ancak aksi halde beklenmedik sonuçları olur. Hem DT1 hem de DT2'ye göre bu değişken sayıda sütun ataması yapmak için RHS'yi ifade etmenin daha titiz/zarif bir yolu var mı?

cevap

0

Bir olasılık katılmak yapmak olduğunu ve sütunları çoğaltılamaz nerede, sen toplamı gerçekleştirmek için bu isimleri kullanmak için bir ifade oluşturabilirsiniz

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

ne dersiniz:

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

teşekkür @ eddi. Çok şık bir çözüm! SetDT işleviyle karşılaşmadım. – sch56

+0

'paste0 ('i.',' Aslında gerekli değil. Data.table'da zaman içinde bu değişiklik mi oldu ya da bunu anlama için kullandınız mı? – andrasz

+0

@andrasz Gerekmediğini söylediğinizde ne demek istediğini anlamıyorum. I.' öneki olmadan sadece DT1'den sütunlar ekliyorsunuz. – eddi

İlgili konular