2 votes

Comment gérer ou ignorer les NAs lors de l'utilisation de ifelse pour muter une nouvelle colonne avec des conditions multiples (résolu)

Je suis un nouveau venu dans dplyr et j'ai essayé de créer une nouvelle variable composite à partir de trois variables d'âge différentes en utilisant dplyr et ifelse . J'ai fait un cadre de données pour expliquer la situation comme suit :

library(dplyr)

z <- data.frame("j6" = c(6, 19, NA, NA, NA, NA, NA, 8, 20, 20, NA), 
                "j7" = c(27, 20, NA, 7, 19, NA, NA, 20, 30, 9, NA),
                "j8" = c(8, 22, NA, 20, NA, 8, 30, NA, NA, NA, 3))

z <- z %>% 
        mutate(., age_event = NA) %>% 
        mutate(., age_event = ifelse(j6 < 18 | j7 < 18 | j8 < 18, 1, 0))

Mes attentes :

  • Les trois colonnes (j6, j7 et j8) indiquent les âges, et si au moins l'un d'entre eux est âgé de moins de 18 ans, la nouvelle colonne (age_event) doit être "1", sinon 0.
  • Et si deux des trois colonnes sont toutes deux âgées de 18 ans ou plus et que l'autre est NA, la variable age_event doit être 0 .
  • De même, si l'une des trois colonnes est 18 ans ou plus et que les autres sont NA, la variable age_event doit être égale à 0.
  • Il est également NA si les trois colonnes sont NA.

Cependant, le résultat et les problèmes sont présentés comme suit :

> z
   j6 j7 j8 age_event
1   6 27  8         1
2  19 20 22         0
3  NA NA NA        NA
4  NA  7 20         1
5  NA 19 NA        NA  <-- should be 0, but NA
6  NA NA  8         1
7  NA NA 30        NA  <-- should be 0, but NA
8   8 20 NA         1
9  20 30 NA        NA  <-- should be 0, but NA
10 20  9 NA         1
11 NA NA  3         1

J'aimerais savoir s'il y a un moyen de transformer les 5ème, 7ème et 9ème observations ci-dessus en 0 en utilisant mutate y ifelse . Toute suggestion serait grandement appréciée !


Mise à jour (27/02/2020) : J'ai trouvé une solution avec pmin lors de l'utilisation de mutate y ifelse :

z <- z %>% 
        mutate(., age_event = ifelse(is.na(j6) & is.na(j7) & is.na(j8), NA,
                              ifelse(pmin(j6, j7, j8, na.rm = T) < 18, 1, 0)))

> z
   j6 j7 j8 age_event
1   6 27  8         1
2  19 20 22         0
3  NA NA NA        NA
4  NA  7 20         1
5  NA 19 NA         0
6  NA NA  8         1
7  NA NA 30         0
8   8 20 NA         1
9  20 30 NA         0
10 20  9 NA         1
11 NA NA  3         1

3voto

Jay Points 1879

Vous pouvez utiliser rowMeans() à la place de if_else() qui traitera les cas qui sont tous NA .

z %>% 
  mutate(age_event = +(rowMeans(. < 18, na.rm = TRUE) > 0))

   j6 j7 j8 age_event
1   6 27  8         1
2  19 20 22         0
3  NA NA NA        NA
4  NA  7 20         1
5  NA 19 NA         0
6  NA NA  8         1
7  NA NA 30         0
8   8 20 NA         1
9  20 30 NA         0
10 20  9 NA         1
11 NA NA  3         1

2voto

Ronak Shah Points 24715

Nous pouvons utiliser rowSums pour calculer le nombre de NA valeurs dans une rangée et le nombre de valeurs qui sont inférieures à 18. Nous pouvons alors utiliser case_when pour attribuer des numéros en fonction de différentes conditions.

library(dplyr)

z %>%
  mutate(calc = rowSums(!is.na(.), na.rm = TRUE),
         ls18 = rowSums(. < 18, na.rm = TRUE), 
         age_event = case_when(calc == 0 & ls18 == 0 ~ NA_integer_,
                               ls18 > 0 ~ 1L, 
                               TRUE ~ 0L)) %>%
   select(-calc, -ls18)

#   j6 j7 j8 age_event
#1   6 27  8         1
#2  19 20 22         0
#3  NA NA NA        NA
#4  NA  7 20         1
#5  NA 19 NA         0
#6  NA NA  8         1
#7  NA NA 30         0
#8   8 20 NA         1
#9  20 30 NA         0
#10 20  9 NA         1
#11 NA NA  3         1

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X