Trouver la position d'index de la première valeur non-NA dans un vecteur R?

J'ai un problème où un vecteur a un tas de NAs au début, et des données par la suite. Cependant, la particularité de mes données est que les premières valeurs N qui ne sont pas NA, ne sont probablement pas fiables, donc je voudrais les supprimer et les remplacer par NA.

Par exemple, si j'ai un vecteur de longueur 20, et que les non-NAs commencent à la position d'index 4:

> z
 [1]          NA          NA          NA -1.64801942 -0.57209233  0.65137286  0.13324344 -2.28339326
 [9]  1.29968050  0.10420776  0.54140323  0.64418164 -1.00949072 -1.16504423  1.33588892  1.63253646
[17]  2.41181291  0.38499825 -0.04869589  0.04798073

Je voudrais supprimer les 3 premières valeurs non-NA, que je crois être peu fiables, pour donner ceci:

> z
 [1]          NA          NA          NA          NA          NA          NA  0.13324344 -2.28339326
 [9]  1.29968050  0.10420776  0.54140323  0.64418164 -1.00949072 -1.16504423  1.33588892  1.63253646
[17]  2.41181291  0.38499825 -0.04869589  0.04798073

De bien sûr, j'ai besoin d'une solution générale et je ne sais jamais quand la première valeur non-NA commence. Comment pourrais-je aller sur le faire? IE Comment puis-je trouver la position d'index de la première valeur non-NA?

Pour être complet, mes données sont en fait disposées dans un cadre de données avec beaucoup de ces vecteurs dans des colonnes, et chaque vecteur peut avoir une position de départ Non-NA différente. De plus, une fois les données démarrées, il peut y avoir des NAs sporadiques plus bas, ce qui m'empêche de simplement compter leur nombre, en tant que solution.

36
r
demandé sur Thomas Browne 2011-07-24 22:02:45

6 réponses

Utilisez une combinaison de is.na et which pour trouver les emplacements d'index non-NA.

NonNAindex <- which(!is.na(z))
firstNonNA <- min(NonNAindex)

# set the next 3 observations to NA
is.na(z) <- seq(firstNonNA, length.out=3)
56
répondu Joshua Ulrich 2011-07-24 18:25:43

Idée similaire à celle de @ Joshua, mais en utilisant which.min()

## dummy data
set.seed(1)
dat <- runif(10)
dat[seq_len(sample(10, 1))] <- NA

## start of data
start <- which.min(is.na(dat))

Qui donne:

> (start <- which.min(is.na(dat)))
[1] 4

Utilisez cette option pour définir start:(start+2) sur NA

is.na(dat) <- seq(start, length.out = 3)

, Résultant en:

> dat
 [1]         NA         NA         NA         NA         NA
 [6]         NA 0.94467527 0.66079779 0.62911404 0.06178627
21
répondu Gavin Simpson 2011-07-24 18:43:00

Si vous traitez des données volumineuses, Position est considérablement plus rapide que which, car il n'évalue que jusqu'à ce qu'une correspondance soit trouvée, plutôt que d'évaluer le vecteur entier.

x=c(rep(NA,3),1:1e8)
Position(function(x)!is.na(x), x)
# 4

On peut attribuer NA aux N valeurs suivantes (ou à la fin du vecteur, selon la première éventualité) par

pos = Position(function(x)!is.na(x), x)
x[pos:min(pos+N-1, length(x))] <- NA
11
répondu dww 2016-08-06 06:36:33

Je ferais quelque chose dans le sens de

# generate some data
tb <- runif(10)
tb[1:3] <- NA

# I convert vector to TRUE/FALSE based on whether it's NA or not
# rle function will tell you when something "changes" in the vector
# (in our case from TRUE to FALSE)
tb.rle <- rle(is.na(tb))

# this is where vector goes from all TRUE to (at least one) FALSE
# your first true number is one position ahead, so +1
tb.rle$lengths[1] 

# you can now subset your vector with the first non-NA value
# and do with it whatever you want. I assign it a fantastic 
# non-believable number
tb[tb.rle$lengths[1] + 1] <- 42
2
répondu Roman Luštrik 2011-07-24 18:26:26

Na.trim() dans le forfait peut vous aider.

library(zoo)
dummy.data <- c(rep(NA, 5), seq(1:7), NA)
x <- length(dummy.data) - length(na.trim(dummy.data, sides = "left"))
dummy.data[(x+1):(x+3)] <- NA
dummy.data
[1] NA NA NA NA NA NA NA NA  4  5  6  7 NA
2
répondu InColorado 2017-05-19 22:31:24

Vous pouvez également utiliser directement la fonction replace (), je sais que la réponse est déjà là mais comme replace () est trop bonne avec ce genre de choses

Par Exemple:

A <- c(1,2,3,4,5,NA,58,NA,98,NA,NA,NA)
which(is.na(A))
A <- replace(A,1:3,NA)
-1
répondu Bharat Kaushik 2018-05-21 11:35:29