3

I have 2 data.frames

df <- data.frame(addr=c('a','b','c','d'), num = c(1,2,3,4))

> df
  addr num
1    a   1
2    b   2
3    c   3
4    d   4

df2 <- data.frame(addr=c('a','b','d'), num=c(100,200,500))

> df2
  addr num
1    a 100
2    b 200
3    d 500

And I would like to replace the values in df$num with the values from df2$num if the condition df$addr matches df2$addr. I managed to get this with the following code

 df[,"num"] <- sapply(df[,"addr"], function(x) ifelse(x %in% df2$addr,df2$num[match(x,df2$addr)],df[df$addr==x,]$num))

> df
  addr num
1    a 100
2    b 200
3    c   3
4    d 500

I was wondering if there is a more elegant method using dplyr or data.table?

andrnev
  • 410
  • 2
  • 12
  • using data.table here is one solution setDT(df)[df2, num := ifelse(addr %in% i.addr ,i.num, num), on = "addr"] – andrnev Jun 11 '18 at 11:39

2 Answers2

3

You can use a combination of left_join and mutate from dplyr

Edit

library(dplyr)

df3 <- df %>% 
  left_join(df2,  by = "addr") %>% 
  mutate(num = ifelse(.$num.y %in% df2$num, .$num.y, df$num)) %>% 
  select(addr, num)

df3
# addr num
#1    a 100
#2    b 200
#3    c   3
#4    d 500

old answer

 df3 <- df %>% 
      mutate(num = ifelse(addr %in% df2$addr, df2$num, num))

df3
#  addr num
#1    a 100
#2    b 200
#3    c   3
#4    d 100
patL
  • 2,259
  • 1
  • 17
  • 38
0

You can just merge the two tables and select the required column:

merge(df,df2,'addr',all = T)
#  addr num.x num.y
#1    a     1   100
#2    b     2   200
#3    c     3    NA
#4    d     4   500
Rohit
  • 1,967
  • 1
  • 12
  • 15