Как заменить значения в одном df значениями из другого df с помощью оператора if - PullRequest
0 голосов
/ 22 января 2019

У меня есть два фрейма данных:

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 находится в df2, тогда я хочу заменить df1 $ date на df2 $ date.Кроме того, если идентификатор в df1 находится в df2, я хочу установить df1 $ result = 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 голосов
/ 22 января 2019

вы можете использовать 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
0 голосов
/ 22 января 2019

Использование поиска:

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
0 голосов
/ 22 января 2019

Если вы хотите продолжить цикл 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

Однако, путь без цикла будет использовать match, где мы рассчитываем индексы для заменытолько один раз и используйте его для изменения значений date и outcome.

inds <- match(df1$ID, df2$ID)
df1$date <- df2$date[inds]
df1$outcome[which(!is.na(inds))] <- 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...