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.