找到R向量中第一个非NA值的索引位置?

时间:2011-07-24 18:02:45

标签: r

我遇到的问题是,矢量在开头有一堆NA,之后有数据。然而,我的数据的特点是前N个非NA的值可能不可靠,所以我想删除它们并用NA替换它们。

例如,如果我有一个长度为20的向量,并且非NAs从索引位置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起始位置。此外,一旦数据开始,可能会出现零星的NAs,这使我无法简单地计算它们的数量,作为解决方案。

7 个答案:

答案 0 :(得分:59)

使用is.nawhich的组合来查找非NA索引位置。

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

# set the next 3 observations to NA
is.na(z) <- seq(firstNonNA, length.out=3)

答案 1 :(得分:21)

与@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

答案 2 :(得分:14)

如果处理大数据,Positionwhich要快得多,因为它只会在找到匹配项之前进行求值,而不是评估整个向量。

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

答案 3 :(得分:2)

我会按照

的方式做点什么
# 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

答案 4 :(得分:2)

动物园包中的

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

答案 5 :(得分:-1)

你也可以直接使用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)

答案 6 :(得分:-1)

这是查找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(which(!is.na(x)))