Supprimer les valeurs NA d'un vecteur

192

J'ai un énorme vecteur qui a quelques NAvaleurs, et j'essaie de trouver la valeur maximale dans ce vecteur (le vecteur est composé de nombres), mais je ne peux pas faire cela à cause des NAvaleurs.

Comment puis-je supprimer les NAvaleurs afin de pouvoir calculer le maximum?

CodeGuy
la source

Réponses:

266

En essayant ?max, vous verrez qu'il a en fait un na.rm =argument, défini par défaut sur FALSE. (C'est la valeur par défaut commun pour de nombreuses autres fonctions de R, y compris sum(), mean(), etc.)

Le réglage na.rm=TRUEfait exactement ce que vous demandez:

d <- c(1, 100, NA, 10)
max(d, na.rm=TRUE)

Si vous souhaitez supprimer tous les NAs, utilisez plutôt cet idiome:

d <- d[!is.na(d)]

Une dernière note: D' autres fonctions (par exemple table(), lm()et sort()) ont des NAarguments qui utilisent des noms concernant la PI (différents et offrent des options différentes). Donc, si cela NAvous pose des problèmes lors d'un appel de fonction, il vaut la peine de rechercher une solution intégrée parmi les arguments de la fonction. J'ai trouvé qu'il y en a généralement un déjà là.

Josh O'Brien
la source
C'est une très mauvaise idée. Il échoue et donne -Infpour un dde tous les NA.
user3932000
@ user3932000 Juste pour être clair pour les autres, votre plainte concerne en fait la façon dont la fonction de base R max()se comporte (comme, par exemple, quand elle le fait max(c(NA, NA)). Personnellement, je pense que son comportement est raisonnable; Je pense qu'il a été construit de cette façon pour que vous obteniez le résultat attendu lorsque vous faites des choses commea <- c(NA, NA); b <- 1:4; max(c(max(a, na.rm = TRUE), max(b, na.rm = TRUE)))
Josh O'Brien
@ user3932000 peu tangentiellement, l' un des nombreux atouts comme une plate - forme d'analyse de données de R est sa gestion sophistiquée des données manquantes, le résultat de beaucoup une réflexion approfondie de la part de ses auteurs. (Si le sujet vous intéresse, voir ici pour une bonne discussion de certains des problèmes impliqués, du point de vue des programmeurs qui étaient engagés dans l'incorporation de fonctionnalités de NAgestion de type R dans l'excellent package NumPy de Python .)
Josh O'Brien
@ user3932000: cette réponse est-elle vraiment mauvaise? Que considérez-vous comme le maximum de l'ensemble nul?
Cliff AB le
@CliffAB Il n'y a pas de maximum. Vous pouvez affecter le max à -∞ (et min à + ∞), mais ce n'est pas toujours souhaité ou intuitif. De plus, lorsque vous supprimez tous les NAs d'un vecteur de NAs, vous vous attendez à un vecteur vide, et non à -∞.
user3932000 le
94

La na.omitfonction est ce que beaucoup de routines de régression utilisent en interne:

vec <- 1:1000
vec[runif(200, 1, 1000)] <- NA
max(vec)
#[1] NA
max( na.omit(vec) )
#[1] 1000
IRTFM
la source
20

?maxvous montre qu'il existe un paramètre supplémentaire na.rmque vous pouvez définir TRUE.

En dehors de cela, si vous voulez vraiment supprimer les NAs, utilisez simplement quelque chose comme:

myvec[!is.na(myvec)]
Nick Sabbe
la source
3
Je pense que c'est mieux. na.rm et na.omit ajoutent un peu de courrier indésirable à la sortie.
MadmanLee du
Sauf a na.omitégalement une méthode dataframe, c'est donc plus général.
IRTFM
15

Vous pouvez appeler max(vector, na.rm = TRUE). Plus généralement, vous pouvez utiliser la na.omit()fonction.

Michael Hoffman
la source
14

Juste au cas où quelqu'un de nouveau chez R voudrait une réponse simplifiée à la question d'origine

Comment puis-je supprimer les valeurs NA d'un vecteur?

C'est ici:

Supposons que vous ayez un vecteur foocomme suit:

foo = c(1:10, NA, 20:30)

courir length(foo)donne 22.

nona_foo = foo[!is.na(foo)]

length(nona_foo) est 21, car les valeurs NA ont été supprimées.

Remember is.na(foo)renvoie une matrice booléenne, donc l'indexation fooavec l'opposé de cette valeur vous donnera tous les éléments qui ne sont pas NA.

Scott C Wilson
la source
13

Utilisation discardde purrr (fonctionne avec des listes et des vecteurs).

discard(v, is.na) 

L'avantage est qu'il est facile d'utiliser des tuyaux; utilisez également la fonction de sous-ensemble intégrée [:

v %>% discard(is.na)
v %>% `[`(!is.na(.))

Notez que na.omitcela ne fonctionne pas sur les listes:

> x <- list(a=1, b=2, c=NA)
> na.omit(x)
$a
[1] 1

$b
[1] 2

$c
[1] NA
qwr
la source
2

J'ai effectué un test rapide comparant les deux baseapproches et il s'avère que x[!is.na(x)]c'est plus rapide que na.omit. L'utilisateur a qwrsuggéré d'essayer purrr::dicardégalement - cela s'est avéré être beaucoup plus lent (même si je serai ravi de prendre connaissance des commentaires sur ma mise en œuvre et mon test!)

microbenchmark::microbenchmark(
  purrr::map(airquality,function(x) {x[!is.na(x)]}), 
  purrr::map(airquality,na.omit),
  purrr::map(airquality, ~purrr::discard(.x, .p = is.na)),
  times = 1e6)

Unit: microseconds
                                                     expr    min     lq      mean median      uq       max neval cld
 purrr::map(airquality, function(x) {     x[!is.na(x)] })   66.8   75.9  130.5643   86.2  131.80  541125.5 1e+06 a  
                          purrr::map(airquality, na.omit)   95.7  107.4  185.5108  129.3  190.50  534795.5 1e+06  b 
  purrr::map(airquality, ~purrr::discard(.x, .p = is.na)) 3391.7 3648.6 5615.8965 4079.7 6486.45 1121975.4 1e+06   c

Pour référence, voici le test original de x[!is.na(x)]vs na.omit:

microbenchmark::microbenchmark(
    purrr::map(airquality,function(x) {x[!is.na(x)]}), 
    purrr::map(airquality,na.omit), 
    times = 1000000)


Unit: microseconds
                                              expr  min   lq      mean median    uq      max neval cld
 map(airquality, function(x) {     x[!is.na(x)] }) 53.0 56.6  86.48231   58.1  64.8 414195.2 1e+06  a 
                          map(airquality, na.omit) 85.3 90.4 134.49964   92.5 104.9 348352.8 1e+06   b
jsavn
la source
vous devriez essayerpurrr:discard
qwr