0

I would like to match two columns based on another. I'm trying to use the match function but gets NA values.

a <- data.frame( x =  c(1,2,3,4,5)) 
b <- data.frame( y =  c(3,4),
                 z = c("A","B"))

a$x <- b$z[match(a$x, b$y)]

I get:
> a
     x
1 <NA>
2 <NA>
3    A
4    B
5 <NA>
I would like :
> a
     x
1    1
2    2
3    A
4    B
5    5

3 Answers 3

1

First, rename the numeric column of b so that you can merge the two data frames:

b <- b %>% rename(x = y)

Then, merge them, turn variables into character and replace the values of column x with those of z if not NA.

a <- merge(a, b, by = "x", all.x = TRUE) %>% 
  mutate_all(as.character) %>% 
  mutate(x = ifelse(is.na(z), x, z))

Result:

  x    z
1 1 <NA>
2 2 <NA>
3 A    A
4 B    B
5 5 <NA>
Sign up to request clarification or add additional context in comments.

Comments

1

Without renaming I would propose this which ends with the same result that broti

tmp.merge<- merge(a,b,by.x = "x", by.y="y", all = TRUE)
for (elm in as.numeric(row.names(tmp.merge[which(!is.na(tmp.merge$z)),]))){
  tmp.merge[elm,'x'] <- as.character(tmp.merge[elm,'z'])
}

tmp.merge

result :

> tmp.merge
  x    z
1 1 <NA>
2 2 <NA>
3 A    A
4 B    B
5 5 <NA>

Comments

1

The following works but you need to set stringsAsFactors = F, when defining dataframe b

a <- data.frame( x =  c(1,2,3,4,10,13,12,11)) 
b <- data.frame( y =  c(10,12,13),
                 z = c("A","B","C"),stringsAsFactors = F)
#
a %>% mutate(x = ifelse(x %in% b$y,b$z[match(x,b$y)],x))

Output

   x
1  1
2  2
3  3
4  4
5  A
6  C
7  B
8 11

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.