如何使用if语句将一个df中的值替换为另一个df中的值

时间:2019-01-22 01:19:21

标签: r

我有两个数据框:

df1 <-data.frame(ID=c(1,2,3,4,5), date=c(NA,NA,NA,NA,NA), outcome=c(NA,1,NA,NA,0))
df1
  ID date outcome
1  1   NA      NA
2  2   NA       1
3  3   NA      NA
4  4   NA      NA
5  5   NA       0

df2 <-data.frame(ID=c(3,25,222,415,700), date=c(010215,032412,040513,041015,120314), outcome=c(1,1,1,1,1))
df2
   ID   date outcome
1   3  10215       1
2  25  32412       1
3 222  40513       1
4 415  41015       1
5 700 120314       1

如果df1中的ID在df2中,那么我想用df2 $ date替换df1 $ date。另外,如果df1中的ID在df2中,我想设置df1 $ outcome =1。我可以使用以下代码执行此操作:

df1$date <-ifelse(df1$ID %in% df2$ID, df2$date[match(df1$ID,df2$ID)],df1$date)
df1$outcome <-ifelse(df1$ID %in% df2$ID, 1,df1$outcome)
df1
  ID  date outcome
1  1    NA      NA
2  2    NA       1
3  3 10215       1
4  4    NA      NA
5  5    NA       0

但是我想了解如何使用一个if语句来做到这一点。我想出了以下代码:

for(i in 1:nrow(df1)){
  if(df1$ID[i] %in% df2$ID){
    df1$outcome[i]==1 & df1$date[i]==df2$date[match(df1$ID,df2$ID)]
  }
}

df1
  ID date outcome
1  1   NA      NA
2  2   NA       1
3  3   NA      NA
4  4   NA      NA
5  5   NA       0

可以正常运行,但不能完成所需的替换。有人可以建议如何修改我所做的工作以使其像第一个代码块一样工作吗?

3 个答案:

答案 0 :(得分:2)

如果要继续进行for循环,一种方法是

for(i in 1:nrow(df1)){
   if(df1$ID[i] %in% df2$ID) {
     df1$date[i] = df2$date[match(df1$ID[i],df2$ID)]
     df1$outcome[i] = 1
   }
}

df1
#  ID  date outcome
#1  1    NA      NA
#2  2    NA       1
#3  3 10215       1
#4  4    NA      NA
#5  5    NA       0

但是,非for循环方式将使用match,在该方法中,我们计算索引仅替换一次,并使用它来更改dateoutcome的值。

inds <- match(df1$ID, df2$ID)
df1$date <- df2$date[inds]
df1$outcome[which(!is.na(inds))] <- 1

答案 1 :(得分:1)

您可以使用coalesce包中的dplyr:您完全不需要使用if-else

library(dplyr)
coalesce(df1, left_join(df1['ID'], df2, by = 'ID'))
  ID  date outcome
1  1    NA      NA
2  2    NA       1
3  3 10215       1
4  4    NA      NA
5  5    NA       0

答案 2 :(得分:0)

使用查找:

df1 <-data.frame(ID=c(1,2,3,4,5), date=c(NA,NA,NA,NA,NA), outcome=c(NA,1,NA,NA,0))
df2 <-data.frame(ID=c(3,25,222,415,700), date=c(010215,032412,040513,041015,120314), outcome=c(1,1,1,1,1))

col_vec <- c("date", "outcome")
df1[ , col_vec] <- lapply(col_vec,
                          function(x) {
                            mask <- is.na(df1[[x]])
                            result <- df1[[x]]
                            result[mask] <- setNames(df2[[x]], df2$ID)[as.character(df1$ID)[mask]]
                            result
                          })
df1
# ID  date outcome
# 1  1    NA      NA
# 2  2    NA       1
# 3  3 10215       1
# 4  4    NA      NA
# 5  5    NA       0