Мутировать на основе двух условий в R-кадре данных - PullRequest
2 голосов
/ 01 февраля 2020

У меня есть R-фрейм данных, который можно сгенерировать из кода ниже

DF <- data.frame("Person_id" = c(1,1,1,1,2,2,2,2,3,3), "Type" = c("IN","OUT","IN","ANC","IN","OUT","IN","ANC","EM","ANC"), "Name" = c("Nara","Nara","Nara","Nara","Dora","Dora","Dora","Dora","Sara","Sara"),"day_1" = c("21/1/2002","21/4/2002","21/6/2002","21/9/2002","28/1/2012","28/4/2012","28/6/2012","28/9/2012","30/06/2004","30/06/2005"),"day_2" = c("23/1/2002","21/4/2002","","","30/1/2012","28/4/2012","","28/9/2012","",""))

Я хотел бы создать два новых столбца как admit_start_date и admit_end_date на основе нескольких условий, которые приведено ниже

Правило 1

  admit_start_date = day_1
  admit_end_date   = day_2 (sometimes day_2 can be NA. So refer Rule 2 below)

Правило 2

   if day_2 is (null or blank or na) and Type is (Out or ANC or EM) then 
         admit_end_date = day_1 
   else (if Type is IN)
         admit_end_date = day_1 + 5 (days)

Это то, что я пытаюсь, но не Кажется, это не помогает

    transform_dates = function(DF){  # this function is to create 'date' columns  
  DF %>% 
    mutate(admit_start_date = day_1) %>% 
    mutate(admit_end_date = day_2) %>%
    admit_end_date = if_else(((Type == 'Out' & admit_end_date.isna() ==True|Type == 'ANC' & admit_end_date.isna() ==True|Type == 'EM' & admit_end_date.isna() ==True),day_1,day_1 + 5)
    )
}  

Как вы можете видеть, я не уверен, как проверить NA для вновь созданного столбца и заменить эти NAs на day_1 или day_1 + 5(days) на основе в столбце Тип.

Не могли бы вы помочь?

Я ожидаю, что мой вывод будет выглядеть так, как показано ниже

enter image description here

1 Ответ

4 голосов
/ 01 февраля 2020

Мы можем использовать case_when, чтобы указать каждое условие отдельно после преобразования столбцов "day" в объекты фактической даты.

library(dplyr)

DF %>%
  mutate_at(vars(starts_with('day')), as.Date, "%d/%m/%Y") %>%
  mutate(admit_start_date = day_1, 
         admit_end_date = case_when(
         !is.na(day_2) ~day_2,
         is.na(day_2) & Type %in% c('OUT', 'ANC', 'EM') ~ day_1, 
         Type == 'IN' ~ day_1 + 5))


#  Person_id Type Name      day_1      day_2 admit_start_date admit_end_date
#1          1   IN Nara 2002-01-21 2002-01-23       2002-01-21     2002-01-23
#2          1  OUT Nara 2002-04-21 2002-04-21       2002-04-21     2002-04-21
#3          1   IN Nara 2002-06-21       <NA>       2002-06-21     2002-06-26
#4          1  ANC Nara 2002-09-21       <NA>       2002-09-21     2002-09-21
#5          2   IN Dora 2012-01-28 2012-01-30       2012-01-28     2012-01-30
#6          2  OUT Dora 2012-04-28 2012-04-28       2012-04-28     2012-04-28
#7          2   IN Dora 2012-06-28       <NA>       2012-06-28     2012-07-03
#8          2  ANC Dora 2012-09-28 2012-09-28       2012-09-28     2012-09-28
#9          3   EM Sara 2004-06-30       <NA>       2004-06-30     2004-06-30
#10         3  ANC Sara 2005-06-30       <NA>       2005-06-30     2005-06-30

Даты в кадре данных не относятся к классу «Дата», (class(DF$day_1)), используя mutate_at, мы меняем их класс на «Дата», чтобы мы могли выполнять математические вычисления над ним. starts_with('day') означает, что любой столбец, имя которого начинается с "day", будет преобразован в класс «Дата». Мы используем mutate_at, когда хотим применить одну и ту же функцию к нескольким столбцам.

case_when является альтернативой вложенным ifelse операторам. Они выполняются в последовательном порядке. Итак, первое условие проверяется, если условие выполнено, остальные условия не проверяются. Если первое условие не выполняется, оно проверяет второе условие и так далее. Следовательно, else здесь не требуется. Если ни одно из условий не выполнено, возвращается NA. Проверьте ?case_when.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...