mrd*_*lar 5 r time-series missing-data
我希望删除时间序列中的值,这些值被NA特定最小长度的块包围.
一些玩具数据:
x = seq(0,10,length.out = 100)
y = sin(x) + rnorm(length(x), mean=0, sd=0.1)
y[20:21] = rep(NA, 2)
y[50:54] = rep(NA, 5)
y[55:59] = seq(-0.1, -0.8, length.out = 5)
y[60:64] = rep(NA, 5)
y[90:91] = rep(NA, 2)
df <- data.frame(x, y)
Run Code Online (Sandbox Code Playgroud)
我希望删除长度小于10且前面跟着5个或更多NA值的任何y值序列.
在我的玩具数据,在索引55-59的y值具有(a)小于连续10个值,并且具有(B)5 NA上两个侧面.因此,应该删除这个值块.
其他值由较长的值块组成和/或由短行程NA(<5)包围,应保留.
绘制要以红色删除的值:
library(ggplot2)
ggplot(data = df, aes(x, y)) +
geom_line() +
geom_line(data = df[55:59, ], color = "red")
Run Code Online (Sandbox Code Playgroud)

首先,我们将定义您指定的两个阈值。(我将第二个设置为 4,这样我们就可以一致地使用“<”和“">”,而不是容易出错的“<”和“">=”)。
threshold.data <- 10
threshold.NA <- 4
Run Code Online (Sandbox Code Playgroud)
现在,关键是使用游程长度编码is.na(y)。看着?rle。
foo <- rle(is.na(y))
foo
Run Code Online (Sandbox Code Playgroud)
首先,我们通过检查原始数据的位置NA(因此foo$values将是TRUE)来提取可能的“NA 候选游程” ,并且我们有指定的最小游程长度NAs:
candidate.runs.NA <- which(foo$values & foo$lengths>threshold.NA)
Run Code Online (Sandbox Code Playgroud)
仅当至少有两次NA运行超过阈值时,我们才想继续:
if ( diff(range(candidate.runs.NA)) >= 2 ) {
Run Code Online (Sandbox Code Playgroud)
NA我们的目标是找到我们想要删除的非数据的索引。为此,我们找到“(非NA)数据的候选运行”。第一步,包括NA上面标识的第一次运行和最后一次运行之间的所有运行:
candidate.runs.data <- seq(candidate.runs.NA[1]+1,tail(candidate.runs.NA,1)-1)
Run Code Online (Sandbox Code Playgroud)
我们通过两个标准来完善这一点。一方面,我们只想要非NAs 的序列,另一方面,这些序列的长度应该低于阈值:
candidate.runs.data <- candidate.runs.data[!foo$values[candidate.runs.data] &
foo$lengths[candidate.runs.data]<threshold.data]
Run Code Online (Sandbox Code Playgroud)
在您的示例中,candidate.runs.data现在只有一个条目 5。这意味着我们需要删除序列第五次运行中的所有数据is.na。为此,我们需要恢复实际索引:
indices.to.remove <- as.vector(sapply(candidate.runs.data,function(kk)
seq(sum(foo$lengths[1:(kk-1)])+1,sum(foo$lengths[1:kk]))))
Run Code Online (Sandbox Code Playgroud)
这有点复杂,因为我将它包装在一个sapply()调用中,以防我们需要删除多个。 candidate.runs.data最后,我们删除这些数据:
y[indices.to.remove] <- NA
}
plot(x,y,"l")
Run Code Online (Sandbox Code Playgroud)

现在,这似乎可以满足您对特定示例的要求。您可能需要考虑在边界情况下希望发生什么。例如,这假设您的系列以非NA. 如果您没有两次运行 5 个或更多NAs,而是运行 3 个或5 个,会发生什么情况?NA“长”跑之间是否有短跑?NA该脚本将把第一次和最后一次“长”运行之间最多九个非 s 的运行视为公平游戏。