3

I'd like to use df1 to update df2, to produce a data frame that looks like df3. Any help would be much appreciated.

df1 <- data.frame(ID=c("D-10003","D-10004"), date=c(2,2), length=c(22,45))
df2 <- data.frame(ID=c("D-10001","D-10003","D-10002","D-10004","D-10005"), date=c(1,NA,NA,NA,2), hair=c(2,3,NA,2,3))
df3 <- data.frame(ID=c("D-10001","D-10003","D-10002","D-10004","D-10005"), date=c(1,2,NA,2,2),hair=c(2,3,NA,2,3))

I've been trying various variations on this, but it always seems to overwrite legitimate entries (eg for ID D-10001, date should remain 1), and I have no clue as to why.

df2$date<-df1[match(df2$ID, df1$ID),2]

3 Answers 3

1

df2$date[is.na(df2$date)] <- df1$date[match(df2$ID[is.na(df2$date)],df1$ID)]

Sign up to request clarification or add additional context in comments.

2 Comments

This is my go to solution for matching situations, I would note that this looks for the first match, not all matches. So, for example, if you had D-10004 twice in df1 with two different date values, it would only map over the first date value.
@D.sen Absolutely yep. Probably should have commented that myself. Beware the duplicates. Thanks.
0

I'd suggest something like this:

sapply(dt1$ID,function(x)dt2$date[dt2$ID==x]<<-dt1$date[dt1$ID==x])

PS: no need to use assinging to anything. It's being assgined from within the function.

Comments

0

Here's a data.table solution:

library(data.table)
setDT(df1)
setDT(df2)
df2[df1, date := df1$date, on = c(ID = "ID")]
#         ID date hair
# 1: D-10001    1    2
# 2: D-10003    2    3
# 3: D-10002   NA   NA
# 4: D-10004    2    2
# 5: D-10005    2    3

As in the first posted answer, there's no need for assignment, as df2 is modified in-place.

Here's another option that protects against overwriting non-NA values, even if the IDs match:

df2[df1, `:=` (date = ifelse(is.na(date), df1$date, date)), on = c(ID = "ID")]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.