Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
找到R向量中第一个非NA值的索引位置?_R - Fatal编程技术网

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

找到R向量中第一个非NA值的索引位置?,r,R,我有一个问题,向量在开始时有一堆NAs,然后是数据。然而,我的数据的特点是,非NA的前n个值可能不可靠,因此我想删除它们并用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

我有一个问题,向量在开始时有一堆NAs,然后是数据。然而,我的数据的特点是,非NA的前n个值可能不可靠,因此我想删除它们并用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进一步下降,这使我无法简单地计算它们的数量作为解决方案。

使用
is.na
的组合来查找非na索引位置

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

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

NonNAindex我会按照

# 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
#生成一些数据

tb与@Joshua的想法类似,但使用了
which.min()

导致:

> dat
 [1]         NA         NA         NA         NA         NA
 [6]         NA 0.94467527 0.66079779 0.62911404 0.06178627

如果处理大数据,
位置
要比
位置
快得多,因为它只在找到匹配之前进行计算,而不是计算整个向量

x=c(rep(NA,3),1:1e8)
Position(function(x) !is.na(x), x)
# 4
我们可以通过以下方式将NA分配给以下N个值(或向量的末尾,以先到者为准):

pos=位置(函数(x)!is.na(x),x)
zoo软件包中的x[pos:min(pos+N-1,length(x))]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
图书馆(动物园)

dummy.data您也可以直接使用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)

该死,这是我的第二个猜测。我很喜欢
rle()
,但我更喜欢这个解决方案。非常感谢。经过一番思考,我提出了min((1:length(z))[!is.na(z)],但当然这是一个更好的想法。PerfectIs
firstNonNA@FlorianJenn:是的,这可能会更快,尤其是对于更大的向量。我想不出在
min
上使用它会有什么问题。对于那些只想删除所有NAs的人(与这个问题的要求有点不同):
x甚至更干净。谢谢,也谢谢你继续回答+1,但我不确定清洁剂。它比较短,但对于那些没有意识到.min将
TRUE
FALSE
分别强制为
1
0
的人来说可能不太清楚。@Joshua同意,它还依赖于.min返回任何绑定最小值中第一个的行为。不确定shorter是否值得接受。在NAs后面紧跟着非NAs的情况下,这一个似乎很难接受,而且这里和那里都有NAs。返回的索引不适用。Joshua详细介绍的解决方案如预期效果。@MatteoCastagna这适用于OPs示例和Q,其中
NA
s位于向量的前面。正如我在评论中提到的,这取决于
which.min()
的行为,这正是它在您描述的情况下失败的原因。是否有一种有效的方法可以做到这一点,即在找到第一个时停止搜索?这在大数据上表现良好无需定义新函数,您可以使用
complete.cases
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
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
A <- c(1,2,3,4,5,NA,58,NA,98,NA,NA,NA)
which(is.na(A))
A <- replace(A,1:3,NA)