2011-07-24 60 views
31

我有一个问题,一个矢量在开始时有一堆NAs,之后有数据。然而,我的数据的特点是前n个非NA值可能不可靠,所以我想删除它们并用NA代替它们。找到R向量中第一个非NA值的索引位置?

例如,如果我在索引位置4的长度为20的矢量,和非NAS开始:

> 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起始位置。同样,一旦数据开始,可能会有更多的零星神经网络进一步下降,这使我无法简单地计算它们的数量,作为解决方案。

+5

有没有一种有效的方法来做到这一点,当它找到第一个时会停止搜索? –

回答

48

使用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) 
+0

当,这是我的第二个猜测。想用'rle()'看中,但我更喜欢这个解决方案。 –

+0

完美的谢谢。经过一番思考,我想出了 分钟((1:长度(z))[!is.na(z)]),但当然这个想法要好得多。完美 –

+3

'firstNonNA < - NonNAindex [1]'更快吗?我会遇到一些使用'[1]'和'min()'的问题吗? –

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 
20

类似的想法到@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 
+0

更清洁。谢谢,也是为了延续答案。 –

+3

+1,但我不清楚清洁。它比较短,但对于没有意识到'which.min'分别将'TRUE'和'FALSE'强制为'1'和'0'的人可能不太清楚。 –

+2

@Joshua同意,它也依赖于which.min返回任何绑定最小值的第一个行为。不确定更短的值得接受。 –

10

如果处理大数据,Positionwhich相当快,因为​​它只直到找到一个匹配,而不是评估全矢量计算。

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

我们可以通过

pos = Position(function(x)!is.na(x), x) 
x[pos:min(pos+N-1, length(x))] <- NA 
+0

这对大数据执行得很好 –

+0

不需要定义一个新函数,可以使用'complete.cases' – Renu

1

na.trim()在动物园包可以帮助分配NA以下的N个值(或载体,以先到者为准的端部)。

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 
相关问题