Comment éviter les avertissements lors de l'introduction des NA par la coercition

124

Je préfère généralement coder R pour ne pas recevoir d'avertissements, mais je ne sais pas comment éviter de recevoir un avertissement lors de l'utilisation as.numericpour convertir un vecteur de caractères.

Par exemple:

x <- as.numeric(c("1", "2", "X"))

Me donnera un avertissement car il a introduit les NA par la coercition. Je veux que les NA soient introduits par la coercition - y a-t-il un moyen de lui dire "oui c'est ce que je veux faire". Ou devrais-je simplement vivre avec l'avertissement?

Ou devrais-je utiliser une fonction différente pour cette tâche?

Korone
la source
8
Vous voyez ?suppressWarningspeut-être?
A5C1D2H2I1M1N2O1R2T1
4
Quel est le problème avec cet avertissement? En général, il donne des informations précieuses. Je préfère une sortie plus verbeuse dans la console R aux mauvaises surprises.
Roland
12
@Roland Je suis tout à fait d'accord, mais l'utilité des avertissements diminue si vous vous habituez à les ignorer. C'est pourquoi j'aime généralement "m'attaquer" aux avertissements. Dans ce cas, je vais TOUJOURS générer des avertissements, et beaucoup d'entre eux - mes données arrivent sous forme de chaînes avec "X" représentant NA, et donc la fonction fait exactement ce que je veux qu'elle fasse. Je voulais dire "Merci de me l'avoir fait savoir, mais c'est bon je sais ce que je fais". suppressWarningssemble parfait.
Korone
6
Vous savez que cela read.tableaccepte un argument na.strings?
Roland
Il est utile de les supprimer si vous avez déjà une solution à un bogue connu dans une bibliothèque. C'est comme ça que je vais utiliser ça!
Clem Wang

Réponses:

142

Utilisez suppressWarnings():

suppressWarnings(as.numeric(c("1", "2", "X")))
[1]  1  2 NA

Cela supprime les avertissements.

Andrie
la source
Bien que ce soit la réponse préférée, la réponse de jangorecki ci-dessous me semble plus solide.
Ian le
34

suppressWarnings()a déjà été mentionné. Une alternative consiste à d'abord convertir manuellement les caractères problématiques en NA. Pour votre problème particulier, faites taRifx::destringexactement cela. De cette façon, si vous obtenez un autre avertissement inattendu de votre fonction, il ne sera pas supprimé.

> library(taRifx)
> x <- as.numeric(c("1", "2", "X"))
Warning message:
NAs introduced by coercion 
> y <- destring(c("1", "2", "X"))
> y
[1]  1  2 NA
> x
[1]  1  2 NA
Ari B. Friedman
la source
3
Je sais que c'est un vieux fil et destringfonctionne parfaitement pour l'exemple d'op, mais une mise en garde pour quiconque verra ce fil à l'avenir est que cela destringfonctionne différemment as.numericlorsque la chaîne cible est un mélange de chaîne et de numérique: c'est-à-dire, destring("x1")donne 1mais as.numeric("x1")donneNA
Hong
26

En général, la suppression des avertissements n'est pas la meilleure solution car vous voudrez peut-être être averti lorsque des entrées inattendues seront fournies.
La solution ci-dessous est un wrapper pour maintenir uniquement NA pendant la conversion du type de données. Ne nécessite aucun paquet.

as.num = function(x, na.strings = "NA") {
    stopifnot(is.character(x))
    na = x %in% na.strings
    x[na] = 0
    x = as.numeric(x)
    x[na] = NA_real_
    x
}
as.num(c("1", "2", "X"), na.strings="X")
#[1]  1  2 NA
jangorecki
la source
4
C'est la meilleure réponse. L'utilisation suppressWarnings()est généralement une mauvaise idée, car nous avons parfois besoin de voir ces avertissements.
keberwein le
0

J'ai légèrement modifié la fonction jangorecki pour le cas où nous pouvons avoir une variété de valeurs qui ne peuvent pas être converties en nombre. Dans ma fonction, une recherche de modèle est effectuée et si le modèle n'est pas trouvé, FALSE est renvoyé.! avant gperl, cela signifie que nous avons besoin des éléments vectoriels qui ne correspondent pas au modèle. Le reste est similaire à la as.numfonction. Exemple:

as.num.pattern <- function(x, pattern){
  stopifnot(is.character(x))
  na = !grepl(pattern, x)
  x[na] = -Inf
  x = as.numeric(x)
  x[na] = NA_real_
  x
}

as.num.pattern(c('1', '2', '3.43', 'char1', 'test2', 'other3', '23/40', '23, 54 cm.'))

[1] 1.00 2.00 3.43   NA   NA   NA   NA   NA
Vladislav Shufinskiy
la source