2015-12-17 48 views
3

我有一個data.table問題,我不確定這是否需要兩個單獨的操作。我有兩個data.tables我想通過特定的列進行合併。但是,如果鍵之間存在匹配,我只想更新結果中的某些列。如果沒有匹配,那麼我想將新數據附加到結果中。列名將始終相同,因此不需要填充。合併兩個data.tables但不更新特定列

實施例遵循:

在本例中,我要通過n2合併,但只改變n3在結果如果有datnew_dat之間的匹配n2值,否則將數據追加從new_datdat

library(data.table) 

## Example data 
dat <- data.table(n1=letters[1:5], n2=letters[11:15], n3=letters[6:10]) 
# n1 n2 n3 
# 1: a k f 
# 2: b l g 
# 3: c m h 
# 4: d n i 
# 5: e o j 

## New data to be updated or appended depending on matching `n2` 
new_dat <- data.table(n1=c('aa', 'z'), n2=c('k', 'xyz'), n3=c('bb', 'b')) 
# n1 n2 n3 
# 1: aa k bb 
# 2: z xyz b 

## Expected outcome: 
## since 'k' is in 'dat' and 'new_dat', don't change 'n1' in merged result (but change 'n3') 
res <- copy(dat) # there doesn't really need to be a copy (only for example) 
res[n2 == 'k', `:=`(n3 = new_dat[n2 == 'k', n1])] # using `:=`() b/c multiple columns 
res <- rbindlist(list(res, new_dat[!(n2 %in% dat$n2)])) 
# n1 n2 n3 
# 1: a k aa 
# 2: b l g 
# 3: c m h 
# 4: d n i 
# 5: e o j 
# 6: z xyz b 

這是否需要兩個步驟:首先更新匹配變量,然後追加不匹配的變量?或者,我可以以某種方式使用合併嗎?

回答

3

由於這實質上是一個具有一些額外條件的外部合併,所以您不能在[運算符中的單個步驟中完成此操作。我會做到以下幾點:

rbind(copy(dat)[new_dat, n3 := i.n1, on = "n2"], new_dat[!dat, on = 'n2']) 
# n1 n2 n3 
#1: a k aa 
#2: b l g 
#3: c m h 
#4: d n i 
#5: e o j 
#6: z xyz b 

(你可以刪除copy如果你不關心修改原始數據)

+0

'i.'是從指定變量的正式命名約定'我的表達''data.table'不會中斷 – eddi

+0

我不記得它在哪裏被記錄。 @阿倫可能會知道。 – eddi

+0

正確 - 您不能通過引用添加行 – eddi