简体   繁体   中英

Merge two data.tables but don't update specific columns

I have a data.table question where I am not sure if this requires two separate operations or not. I have two data.tables I want to merge by specific columns. However, if there is a match between the keys, I only want to update some of the columns in the result. If there is no match then I want to append the new data to the result. The column names will always be the same, so there is no filling necessary.

Example to follow:

In this example, I want to merge by n2 , but only change n3 in the result if there is a matching n2 value between dat and new_dat , otherwise append the data from new_dat to dat .

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

Does this require two steps: first updating matching variables, then appending non-matching ones? Or, can I use a merge somehow?

Since this is essentially an outer merge with some extra conditions, you can't do it in a single step within the [ operator. I'd do the following:

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

(you can remove the copy if you don't care about the modifications to the original data)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM