web-dev-qa-db-fra.com

Syntaxe correcte pour mutate_if

Je voudrais remplacer les valeurs de NA par des zéros via mutate_if Dans dplyr. La syntaxe ci-dessous:

set.seed(1)
mtcars[sample(1:dim(mtcars)[1], 5),
       sample(1:dim(mtcars)[2], 5)] <-  NA

require(dplyr)

mtcars %>% 
    mutate_if(is.na,0)

mtcars %>% 
    mutate_if(is.na, funs(. = 0))

renvoie une erreur:

Erreur dans vapply(tbl, p, logical(1), ...): les valeurs doivent avoir la longueur 1, mais FUN(X[[1]]) le résultat est la longueur 32

Quelle est la syntaxe correcte pour cette opération?

44
Konrad

J'ai appris cette astuce du tutoriel purrr , et cela fonctionne aussi dans dplyr. Il y a deux façons de résoudre ce problème:
Définissez d’abord des fonctions personnalisées en dehors du canal, puis utilisez-les dans mutate_if():

any_column_NA <- function(x){
    any(is.na(x))
}
replace_NA_0 <- function(x){
    if_else(is.na(x),0,x)
}
mtcars %>% mutate_if(any_column_NA,replace_NA_0)

Deuxièmement, utilisez la combinaison de ~, . Ou .x. (.x Peut être remplacé par ., Mais aucun autre caractère ou symbole):

mtcars %>% mutate_if(~ any(is.na(.x)),~ if_else(is.na(.x),0,.x))
#This also works
mtcars %>% mutate_if(~ any(is.na(.)),~ if_else(is.na(.),0,.))

Dans votre cas, vous pouvez aussi utiliser mutate_all():

mtcars %>% mutate_all(~ if_else(is.na(.x),0,.x))

En utilisant ~, Nous pouvons définir une fonction anonyme, tandis que .x Ou . Représente la variable. Dans mutate_if() cas, . Ou .x Correspond à chaque colonne.

33
Yifu Yan

Le "si" dans mutate_if Fait référence au choix colonnes, pas aux lignes. Par exemple, mutate_if(data, is.numeric, ...) signifie effectuer une transformation sur toutes les colonnes numériques de votre jeu de données.

Si vous souhaitez remplacer toutes les NA par des zéros dans les colonnes numériques:

data %>% mutate_if(is.numeric, funs(ifelse(is.na(.), 0, .)))
43
Hong Ooi
mtcars %>% mutate_if(is.numeric, replace_na, 0)
11
Nettle

Nous pouvons utiliser set de data.table

library(data.table)
setDT(mtcars)
for(j in seq_along(mtcars)){
  set(mtcars, i= which(is.na(mtcars[[j]])), j = j, value = 0)
 }
3
akrun

Je lutte toujours avec la fonction replace_na de dplyr

  replace(is.na(.),0)

cela fonctionne pour moi pour ce que vous essayez de faire.

0
Ashish Singhal