Найти позицию индекса первого не-значения NA в векторе R? - PullRequest
39 голосов
/ 24 июля 2011

У меня проблема в том, что у вектора в начале есть куча NA, а затем данные. Однако особенность моих данных в том, что первые n значений, которые не являются NA, вероятно, ненадежны, поэтому я хотел бы удалить их и заменить их на NA.

Например, если у меня есть вектор длины 20, а не-NA начинаются с позиции индекса 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

Я хотел бы удалить первые 3 значения, отличные от NA, которые я считаю ненадежными, чтобы получить следующее:

> 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

Конечно, мне нужно общее решение, и я никогда не знаю, когда начинается первое не-NA значение. Как бы я поступил так? IE как мне узнать позицию индекса первого не-NA значения?

Для полноты, мои данные фактически упорядочены во фрейме данных с множеством этих векторов в столбцах, и каждый вектор может иметь свою начальную позицию, отличную от NA. Кроме того, после запуска данных могут возникать спорадические NA, что не позволяет мне просто считать их количество в качестве решения.

Ответы [ 7 ]

59 голосов
/ 24 июля 2011

Используйте комбинацию is.na и which, чтобы найти местоположения индекса, отличного от NA.

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

# set the next 3 observations to NA
is.na(z) <- seq(firstNonNA, length.out=3)
21 голосов
/ 24 июля 2011

Аналогично идее @Joshua, но с использованием 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))

, что дает:

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

Используйте это, чтобы установить start:(start+2) на NA

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

в результате:

> dat
 [1]         NA         NA         NA         NA         NA
 [6]         NA 0.94467527 0.66079779 0.62911404 0.06178627
14 голосов
/ 06 августа 2016

При работе с большими данными, Position значительно быстрее, чем which, потому что он вычисляет только до тех пор, пока не будет найдено соответствие, а не оценивает весь вектор.

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

Мы можем присвоить NA следующим значениям N (или концу вектора, в зависимости от того, что наступит раньше) на

pos = Position(function(x)!is.na(x), x)
x[pos:min(pos+N-1, length(x))] <- NA
2 голосов
/ 20 мая 2017

na.trim () в пакете зоопарка может помочь.

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 голосов
/ 24 июля 2011

Я бы сделал это что-то вроде

# 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
0 голосов
/ 25 февраля 2019

Вот самый простой способ найти позиции элементов NA

# 1. Data with NA
x <- c(1:6, NA, NA, 9:12)

# 2. Position of NA elements
seq(along = x)[is.na(x)]
which(is.na(x))

РЕДАКТИРОВАТЬ с помощью OP:

требуется!

min (который (! Is.na(х)))

0 голосов
/ 21 мая 2018

Вы также можете напрямую использовать функцию replace (), я знаю, что ответ уже есть, но как replace () слишком хорош для такого рода вещей

Например -:

A <- c(1,2,3,4,5,NA,58,NA,98,NA,NA,NA)
which(is.na(A))
A <- replace(A,1:3,NA)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...