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.