Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

updating column in one dataframe with value from another dataframe based on matching values

Tags:

r

I have a data frame "z"

   letter color 1       a     0 2       e     0 3       b     0 4       b     0 5       d     0 6       d     0 7       a     0 8       b     0 9       c     0 10      d     0 11      c     0 12      c     0 13      c     0 14      c     0 15      e     0 16      e     0 17      a     0 18      d     0 19      e     0 20      b     0 

and another data frame "y"

  letter color 1      a   red 2      b  blue 3      c green 

when the letter in z matches with a letter in y I would like to append the color from y into the corresponding color field in z but I do not want to remove any values from z. If a match doesn't occur, z$color should remain unchanged. I used"0" as a place holder in z$color, this could be text instead.

I've been attempting things for loops, the match() command and statements with %in% but I'm not quite achieving the results I'm after.

Any ideas?

This is the code I used for the data frames

set.seed(3) z=data.frame(sample(c("a","b","c","d","e"),20,replace=T)) names(z)="letter" z$color=rep(0,dim(z)[1]) z  y1=c("a","b","c") y2=c("red","blue","green") y=data.frame(cbind(y1,y2)) names(y)=c("letter","color") y 
like image 598
Will Phillips Avatar asked Feb 11 '14 20:02

Will Phillips


People also ask

When two DataFrame column values are matched with each other it is called?

Combining DataFrames using a common field is called “joining”. The columns containing the common values are called “join key(s)”. Joining DataFrames in this way is often useful when one DataFrame is a “lookup table” containing additional data that we want to include in the other.


2 Answers

you don't need z$color in the first place if its just place holder, you can replace NA later with 0

z$color<-y[match(z$letter, y$letter),2] 
like image 105
Ananta Avatar answered Sep 21 '22 23:09

Ananta


You can use merge:

dat <- merge(z, y, by = "letter", all.x = TRUE) transform(dat, color = ifelse(is.na(color.y),                                color.x, as.character(color.y)))[-(2:3)]     letter color 1       a   red 2       a   red 3       a   red 4       b  blue 5       b  blue 6       b  blue 7       b  blue 8       c green 9       c green 10      c green 11      c green 12      c green 13      d     0 14      d     0 15      d     0 16      d     0 17      e     0 18      e     0 19      e     0 20      e     0 
like image 45
Sven Hohenstein Avatar answered Sep 23 '22 23:09

Sven Hohenstein