根据另一列中的匹配条件替换列

时间:2020-04-01 09:40:27

标签: r dataframe merge

我想根据另一列匹配两列。我正在尝试使用match函数,但获取NA值。

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 个答案:

答案 0 :(得分:1)

首先,重命名b的数字列,以便可以合并两个数据框:

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

然后,合并它们,将变量转换为字符,如果不是NA,则将列x的值替换为z的值。

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

结果:

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

答案 1 :(得分:1)

如果不重命名,我建议这样做,其结果与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

结果:

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

答案 2 :(得分:1)

以下方法可行,但是在定义数据帧stringsAsFactors = F时需要设置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))

输出

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