web-dev-qa-db-fra.com

Éviter les conflits de types avec dplyr :: case_when

J'essaie d'utiliser dplyr::case_when dans dplyr::mutate pour créer une nouvelle variable dans laquelle je mets certaines valeurs à manquant et recode d'autres valeurs simultanément.

Cependant, si j'essaie de définir des valeurs sur NA, j'obtiens une erreur indiquant que nous ne pouvons pas créer la variable new car NAs sont logiques:

Erreur dans mutate_impl (.data, dots):
Erreur d'évaluation: doit être de type double et non logique.

Existe-t-il un moyen de définir des valeurs sur NA dans un vecteur non logique dans une trame de données en utilisant cela?

library(dplyr)    

# Create data
df <- data.frame(old = 1:3)

# Create new variable
df <- df %>% dplyr::mutate(new = dplyr::case_when(old == 1 ~ 5,
                                                  old == 2 ~ NA,
                                                  TRUE ~ old))

# Desired output
c(5, NA, 3)
23
user3614648

Comme indiqué dans ?case_when:

Tous les RHS doivent évaluer le même type de vecteur.

Vous avez en fait deux possibilités:

1) Créer new comme vecteur numérique

df <- df %>% mutate(new = case_when(old == 1 ~ 5,
                                    old == 2 ~ NA_real_,
                                    TRUE ~ as.numeric(old)))

Notez que NA_real_ est la version numérique de NA, et que vous devez convertir old en numérique car vous l'avez créé sous forme d'entier dans votre trame de données d'origine.

Vous recevez:

str(df)
# 'data.frame': 3 obs. of  2 variables:
# $ old: int  1 2 3
# $ new: num  5 NA 3

2) Créer new comme vecteur entier

df <- df %>% mutate(new = case_when(old == 1 ~ 5L,
                                    old == 2 ~ NA_integer_,
                                    TRUE ~ old))

Ici, 5L force 5 dans le type entier et NA_integer_ est la version entière de NA.

Donc cette fois new est entier:

str(df)
# 'data.frame': 3 obs. of  2 variables:
# $ old: int  1 2 3
# $ new: int  5 NA 3
35
Scarabee

Essaye ça ?

df %>% dplyr::mutate(new = dplyr::case_when(.$old == 1 ~ 5,
                                                  .$old == 2 ~ NA_real_,
                                                  TRUE~.$old))

> df
  old new
1   1   5
2   2  NA
3   3   3
2
WeNYoBen