有条件地使用第二个数据帧中的值替换数据帧中的值

时间:2016-01-22 18:54:13

标签: r dataframe

假设我有一个数据框d1,如下所示:

  site code trait
1    1    A   1.0
2    2    B   1.3
3    3    A    NA
4    4    B   2.9
5    5    A    NA

以下是生成d1的输入:

structure(list(site = 1:5, code = structure(c(1L, 2L, 1L, 2L, 
1L), .Label = c("A", "B"), class = "factor"), trait = c(1, 1.3, 
NA, 2.9, NA)), .Names = c("site", "code", "trait"), row.names = c(NA, 
-5L), class = "data.frame")

我有第二个数据框d2,如下所示:

  code trait
1    A   1.5
2    B   2.5

以下是生成d2的输入:

structure(list(code = structure(1:2, .Label = c("A", "B"), class = "factor"), 
    trait = c(1.5, 2.5)), .Names = c("code", "trait"), row.names = c(NA, 
-2L), class = "data.frame")

我想要一段代码替换trait的NA值,其中d2的特征值与code中特定行的d1字符相匹配。 d1的最终输出如下所示:

  site code trait
1    1    A   1.0
2    2    B   1.3
3    3    A   1.5
4    4    B   2.9
5    5    A   1.5

我尝试的事情:

d1$trait<- ifelse(is.na(d1$trait),d2$trait[d2$code == d1$code],d1$trait)

使用此代码时,我收到警告:

  

警告信息:1:在is.na(e1)|中is.na(e2):较长的物体长度   不是较短对象长度2的倍数:在==。默认值(d2 $ code,   d1 $ code):较长的对象长度不是较短对象的倍数   长度

3 个答案:

答案 0 :(得分:3)

您的ifelse语法很接近,但问题是:

d2$trait[d2$code == d1$code]

在这里,您尝试查找与d2$trait中正确的code值对应的d1值,但实际上您只是在比较d2$code的相应元素到d1$code。可以使用match

来完成操作
d1$trait<- ifelse(is.na(d1$trait),d2$trait[match(d1$code, d2$code)], d1$trait)
d1
#   site code trait
# 1    1    A   1.0
# 2    2    B   1.3
# 3    3    A   1.5
# 4    4    B   2.9
# 5    5    A   1.5

另一种方法是只替换缺失的值,再次使用match来抓取d2$trait中的相关元素:

d1$trait[is.na(d1$trait)] <- d2$trait[match(d1$code[is.na(d1$trait)], d2$code)]
d1
#   site code trait
# 1    1    A   1.0
# 2    2    B   1.3
# 3    3    A   1.5
# 4    4    B   2.9
# 5    5    A   1.5

虽然matchmerge在内部执行非常相似的操作,但我发现match语法更容易使用,因为您不需要创建中间体通过merge对象,然后从该中间对象中获取相关信息。

答案 1 :(得分:2)

这是一个简单的合并任务:

df12 <- merge(df1, df2, by="code", all.x=TRUE)
df12$trait <- ifelse(is.na(df12$trait.x), df12$trait.y, df12$trait.x)

答案 2 :(得分:1)

您也可以在没有使用dplyr之类管道的中间对象的情况下完成此操作:

library(dplyr)

full_join(df1, df2, by="code") %>%
  mutate(trait=ifelse(is.na(trait.x), trait.y, trait.x)) %>%
  select(site, code, trait)

这里的优点是您不需要中间对象期间,并且您已准备好开始使用管道中的数据。