用ID替换另一个数据帧中的值

时间:2016-10-21 12:50:29

标签: r dataframe

我有两个数据框::

as1 <- data.frame(ID = c(1,2,3,4,5,6),
                  pID = c(21,22,23,24,25,26),
                  Values = c(435,33,45,NA, NA,12))
as2 <- data.frame(ID = c(4,5),
                  pid = c(24,25),
                  Values = c(544, 676))

我需要通过匹配ID和pID

将as1中的NA值替换为as2中的NA值

我需要将结果数据框作为:

  resultdf
    ID pID Values
    1  1  21    435
    2  2  22     33
    3  3  23     45
    4  4  24    544
    5  5  25    676
    6  6  26     12

我尝试了子集,然后na.omit()然后rbind ...但我正在丢失索引。

4 个答案:

答案 0 :(得分:4)

以下是两个基本的R解决方案。

首先,使用“ID”中的match选择as1中“Value”的元素来填写:

as1$Values[match(as2$ID, as1$ID)] <- as2$Values

as1
  ID pID Values
1  1  21    435
2  2  22     33
3  3  23     45
4  4  24    544
5  5  25    676
6  6  26     12

仅当ID是两个数据集的真实ID(即pid“无关紧要”)时才有效。其次,如果还需要pid,您可以使用merge然后“折叠”两个值列,如下所示:

df <- merge(as1, as2, by.x=c("ID", "pID"), by.y=c("ID", "pid"), all=TRUE)

这将生成一个包含两个值列的四列数据框。将这些内容与ifelse

折叠为一个列
df <- cbind(df[c(1,2)], "Values"=with(df, ifelse(is.na(Values.y), Values.x, Values.y)))

df
  ID pID Values
1  1  21    435
2  2  22     33
3  3  23     45
4  4  24    544
5  5  25    676
6  6  26     12

答案 1 :(得分:4)

根据Marta的dplyr解决方案,我们可以使用coalesce来合并合并的Value.xValue.y

library(dplyr)
res <- as1 %>% left_join(as2, by = c("ID", "pID"="pid")) %>%
               mutate(Values=coalesce(Values.x,Values.y)) %>%
               select(-Values.x,-Values.y)
##  ID pID Values
##1  1  21    435
##2  2  22     33
##3  3  23     45
##4  4  24    544
##5  5  25    676
##6  6  26     12

还请注意byleft_join参数的语法。在此,我们IDpID加入as1pid加入as2

答案 2 :(得分:3)

尝试使用dplyr库。首先连接两个表,然后使用值NA创建新列:

library("dplyr")

as1 <- data.frame(ID = c(1,2,3,4,5,6), pid = c(21,22,23,24,25,26),Values = c(435,33,45,NA, NA,12))
as2 <- data.frame(ID = c(4,5),pid = c(24,25), Values = c(544, 676))

left_join(as1, as2, by = c("ID", "pid")) %>% 
    mutate(Values = ifelse(is.na(Values.x), Values.y, Values.x)) %>% 
    select(ID, pid, Values)

# ID pid Values
# 1  1  21    435
# 2  2  22     33
# 3  3  23     45
# 4  4  24    544
# 5  5  25    676
# 6  6  26     12

答案 3 :(得分:1)

或另一个选项是data.table

library(data.table)
setDT(as1)[as2, Values := i.Values , on =.(ID, pid)]
as1
#    ID pid Values
#1:  1  21    435
#2:  2  22     33
#3:  3  23     45
#4:  4  24    544
#5:  5  25    676
#6:  6  26     12