I have two data frames. The first looks like this:
value <- seq(1, 100, length.out=20)
df1 <- data.frame(id=as.character(1:20),
value=value,
stringsAsFactors=F)
I have a second dataframe that looks like this
df2 <- data.frame(id=as.character(c(1:5, 21:23)),
v2=NA,
stringsAsFactors=F)
I need the values transferring from df1
to df2
, but only where df1$id == df2$id
. So the dataframe I need is:
df2Needed <- data.frame(id=as.character(c(1:5, 21:23)),
v2=c(value[1:5], NA, NA, NA),
stringsAsFactors=F)
Is there a way to do this?
Using data.table
:
require(data.table)
dt1 <- data.table(df1, key="id")
dt2 <- data.table(df2)
dt1[dt2$id, value]
# id value
# 1: 1 1.000000
# 2: 2 6.210526
# 3: 3 11.421053
# 4: 4 16.631579
# 5: 5 21.842105
# 6: 21 NA
# 7: 22 NA
# 8: 23 NA
or using base merge
as @TheodoreLytras mentioned under comment:
# you don't need to have `v2` column in df2
merge(df2, df1, by="id", all.x=T, sort=F)
# id v2 value
# 1 1 NA 1.000000
# 2 2 NA 6.210526
# 3 3 NA 11.421053
# 4 4 NA 16.631579
# 5 5 NA 21.842105
# 6 21 NA NA
# 7 22 NA NA
# 8 23 NA NA
One way to do this using merge()
:
df2Needed <- merge(df2,df1,by="id",all.x=TRUE, sort=FALSE)
df2Needed <- df2Needed[,c("id","value")]
colNames(df2Needed) <- c("id","v2")
and another (more elegant, I think) using match()
:
df2Needed <- df2
df2Needed$v2 <- df1$value[match(df2$id, df1$id)]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With