2017-10-11 4 views
1

J'utilise dplyr et ifelse pour créer une nouvelle colonne basée sur deux conditions avec les données ci-dessous.Conditionnel imbriqué dans instruction ifelse dplyr

dat <- structure(list(GenIndID = c("BHS_034", "BHS_034", "BHS_068", 
"BHS_068", "BHS_068", "BHS_068", "BHS_068", "BHS_068", "BHS_068", 
"BHS_068", "BHS_068"), IndID = c("BHS_034_A", "BHS_034_A", "BHS_068_A", 
"BHS_068_A", "BHS_068_A", "BHS_068_A", "BHS_068_A", "BHS_068_A", 
"BHS_068_A", "BHS_068_A", "BHS_068_A"), Fate = c("Mort", "Mort", 
"Alive", "Alive", "Alive", "Alive", "Alive", "Alive", "Alive", 
"Alive", "Alive"), Status = c("Alive", "Mort", "Alive", "Alive", 
"MIA", "Alive", "MIA", "Alive", "MIA", "Alive", "Alive"), Type = c("Linked", 
"Linked", "SOB", "SOB", "SOB", "SOB", "SOB", "SOB", "SOB", "SOB", 
"SOB"), SurveyID = c("GYA13-1", "GYA14-1", "GYA13-1", "GYA14-1", 
"GYA14-2", "GYA15-1", "GYA16-1", "GYA16-2", "GYA17-1", "GYA17-3", 
"GYA15-2"), SurveyDt = structure(c(1379570400, 1407477600, 1379570400, 
1407477600, 1409896800, NA, 1462946400, 1474351200, 1495519200, 
1507010400, 1441951200), tzone = "", class = c("POSIXct", "POSIXt" 
))), row.names = c(NA, 11L), .Names = c("GenIndID", "IndID", 
"Fate", "Status", "Type", "SurveyID", "SurveyDt"), class = "data.frame") 

> dat 
    GenIndID  IndID Fate Status Type SurveyID SurveyDt 
1 BHS_034 BHS_034_A Mort Alive Linked GYA13-1 2013-09-19 
2 BHS_034 BHS_034_A Mort Mort Linked GYA14-1 2014-08-08 
3 BHS_068 BHS_068_A Alive Alive SOB GYA13-1 2013-09-19 
4 BHS_068 BHS_068_A Alive Alive SOB GYA14-1 2014-08-08 
5 BHS_068 BHS_068_A Alive MIA SOB GYA14-2 2014-09-05 
6 BHS_068 BHS_068_A Alive Alive SOB GYA15-1  <NA> 
7 BHS_068 BHS_068_A Alive MIA SOB GYA16-1 2016-05-11 
8 BHS_068 BHS_068_A Alive Alive SOB GYA16-2 2016-09-20 
9 BHS_068 BHS_068_A Alive MIA SOB GYA17-1 2017-05-23 
10 BHS_068 BHS_068_A Alive Alive SOB GYA17-3 2017-10-03 
11 BHS_068 BHS_068_A Alive Alive SOB GYA15-2 2015-09-11 

Plus précisément, le regroupement par GenIndID Je veux faire un nouveau champ de date qui est le maximum SurveyDt basé sur un deux conditionals pour Type et Fate. En outre, je veux que la date maximale pour évaluer uniquement SurveyDt lorsque Status == Alive. Mon code ci-dessous produit toutes les valeurs NA, plutôt que le champ de date décrit pour BHS_068 qui répond à toutes les conditions spécifiées.

J'ai récemment vu case_when qui peut être approprié ici, mais je ne pouvais pas l'implémenter correctement.

dat %>% group_by(GenIndID) %>% 
    mutate(NewDat = as.POSIXct(ifelse(Type == "SOB" & Fate == "Alive", max(SurveyDt[Status == "Alive"], na.rm = F), NA), 
          origin='1970-01-01', na.rm=T)) %>% 
    as.data.frame() 

Toutes les suggestions seraient appréciées.

+0

Pouvez-vous fournir un tableau indiquant comment la sortie désirée ressemblerait? – Cris

Répondre

2

Si vous voulez coller avec dplyr et utiliser case_when vous devez vous assurer que vos valeurs pour chacune des déclarations de cas sont du même type.

Dans ce cas, votre valeur TRUE sera datetime, vous devez donc également définir la valeur par défaut comme date/heure en l'entourant de as.POSIXct.

dat %>% 
    group_by(GenIndID) %>% 
    mutate(NewDat = case_when(Type == "SOB" & Fate == "Alive" ~ max(SurveyDt[Status == "Alive"], na.rm = TRUE), 
          TRUE ~ as.POSIXct(NA, origin = "1970-01-01"))) 

En utilisant ifelse

dat %>% 
    group_by(GenIndID) %>% 
    mutate(NewDat = ifelse(Type == "SOB" & Fate == "Alive", 
         max(SurveyDt[Status == "Alive"], na.rm = TRUE), 
         as.POSIXct(NA, origin = "1970-01-01"))) 
+0

Je ne suis pas lié à 'case_when' si le même résultat est possible avec' ifelse' car je suis plus familier avec cette syntaxe. –

+0

Pour 'case_when' est le' TRUE ~ as.POSIXct (NA, origin = "1970-01-01" 'fournissant la partie' else' d'un 'ifelse', c'est-à-dire, le remplissage pour les lignes où les conditions spécifiées Je n'ai pas été capable de l'interpréter à partir du fichier d'aide (avec ma capacité de r ...). –

2

Nous pourrions utiliser data.table. Après la conversion à data.table (setDT(dat)), spécifiez la i comme la comparaison logique, regroupés par 'GenIndID', nous affectons (:=), le max de 'SurveyDt' où le 'Statut' est "Alive" à 'NewDat'

library(data.table) 
setDT(dat)[Type == "SOB" & Fate == "Alive", 
     NewDat := max(SurveyDt[Status == "Alive"], na.rm = TRUE), GenIndID]