J'ai un vecteur:
c(NA,1:5,NA,NA,1:3)
Et je dois supprimer une queue avec NA.
Finalement, le résultat sera:
a<-c(NA,1:5,NA,NA,1:3, rep(NA,round(runif(1,0,100))))
6 Réponses :
Une option serait
(a <- c(NA, 1:5, NA, NA, 1:3, NA, NA)) # [1] NA 1 2 3 4 5 NA NA 1 2 3 NA NA is.na(a) # [1] TRUE FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE TRUE TRUE rev(is.na(a)) # [1] TRUE TRUE FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE TRUE cumprod(rev(is.na(a))) # [1] 1 1 0 0 0 0 0 0 0 0 0 0 0 rev(cumprod(rev(is.na(a)))) # [1] 0 0 0 0 0 0 0 0 0 0 0 1 1
Voici les étapes:
a[rev(cumprod(rev(is.na(a)))) == 0] # [1] NA 1 2 3 4 5 NA NA 1 2 3
Je pense que cela fonctionne:
rm_NA_tail <- function(a) { if (is.na(a[length(a)])) { return(a[is.na(match(data.table::rleid(a), max(data.table::rleid(a))))]) } else { return(a) } }
Vous pouvez faire
a[1:max(which(!is.na(a)))] # [1] NA 1 2 3 4 5 NA NA 1 2 3
Nous sous-ensembles le vecteur de la position 1 à la dernière valeur non NA.
Celui-ci échoue dans le cas (probablement très improbable) où a
ne contient que NA
.
Vous pouvez trouver la position maximale qui n'est pas un NA et sous-ensemble en conséquence
> a[1:max(which(!is.na(a)))] [1] NA 1 2 3 4 5 NA NA 1 2 3
Également une possibilité:
library(microbenchmark) a <- rep(a, 1e5) microbenchmark( markus = a[1:max(which(!is.na(a)))], Julius_Vainora = a[rev(cumprod(rev(is.na(a)))) == 0], Kim = rm_NA_tail(a), tmfmnk = a[cumsum(!is.na(a)) != max(cumsum(!is.na(a))) * is.na(a)], nsinghs = a[1:(length(a) - rle(is.na(rev(a)))$lengths[1])], times = 5 ) Unit: milliseconds expr min lq mean median uq max neval cld markus 150.7346 153.0674 156.4194 153.3031 159.4718 165.5201 5 a Julius_Vainora 393.8520 418.8186 616.3269 703.4022 749.6600 815.9018 5 bc Kim 370.7680 382.1826 536.0828 632.0031 642.1882 653.2720 5 bc tmfmnk 390.2626 415.2378 466.4245 415.8310 423.3828 687.4082 5 b nsinghs 537.0404 781.1403 798.6929 793.1027 842.6777 1039.5033 5 c
En étapes individuelles:
is.na(a) [1] TRUE FALSE FALSE FALSE FALSE cumsum(!is.na(a)) [1] 0 1 2 3 4 cumsum(!is.na(a)) != max(cumsum(!is.na(a))) [1] TRUE TRUE TRUE TRUE TRUE cumsum(!is.na(a)) != max(cumsum(!is.na(a))) * is.na(a) [1] TRUE TRUE TRUE TRUE TRUE
Juste pour le plaisir, un petit benchmarking:
XXX
Cela peut être fait en utilisant rle()
a[1:(length(a) - rle(is.na(rev(a)))$lengths[1])] # [1] NA 1 2 3 4 5 NA NA 1 2 3
rle (is.na (rev (a))) $ lengths [1] obtient le nombre de
NA
de fin dans le vecteur, puis soustrait-le de la longueur
totale du vecteur pour obtenir l'index jusqu'à lequel vous souhaitez conserver le vecteur.