识别数据块

Identify data blocks

我有一个带有负值或 NA 和阈值的向量:

threshold <- -1

example <- c(NA, NA, -0.108, NA, NA, NA, NA, NA -0.601, -0.889, -1.178, -1.089, -1.401, -1.178, -0.959, -1.085, -1.483, -0.891, -0.817, -0.095, -1.305, NA, NA, NA, NA, -0.981, -0.457, -0.003, -0.358, NA, NA)

我想识别所有至少有一个值低于阈值的数据块,并用 NA 替换所有其他块。使用我的示例向量,我想要这个结果:

result <- c(NA, NA, NA, NA, NA, NA, NA, NA -0.601, -0.889, -1.178, -1.089, -1.401, -1.178, -0.959, -1.085, -1.483, -0.891, -0.817, -0.095, -1.305, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)

所以第一个可用值是第一个块,但是-0.108 高于-1,所以它变成了 NA。第二个块保持不变,因为至少有一个值低于-1。第三块现在是 NA 值,因为在 4 个可用值之间,没有一个低于阈值。

我的第一个想法是确定哪些值低于阈值:

val <- which(example < threshold)

但是我不知道怎么说 "keep all the values around this position which are not NA" 因为它总是有不同数量的值...

尝试

library(data.table)#v >= 1.9.5 (devel version - install from GitHub).
#library(devtools)
#install_github("Rdatatable/data.table", build_vignettes = FALSE)
as.data.table(example)[, res:=(NA | (min(example)< -1))*example, by=rleid(is.na(example))][, res]

另一种方式,在 OlliJ 的建议下:

example <- c(NA, NA, -0.108, NA, NA, NA, NA, NA -0.601, -0.889, -1.178, -1.089, -1.401, -1.178, -0.959, -1.085, -1.483, -0.891, -0.817, -0.095, NA, NA, NA, NA, -0.981, -0.457, -0.003, -0.358, NA, NA)
test <- !(is.na(example))

len <- rle(test)$lengths
val <- rle(test)$values

##Matrix with the beginning and the end of each group
ind <- matrix(,nrow=length(which(val)),ncol=2)
ind[,1] <- (cumsum(len)[which(val==T)-1])+1
ind[,2] <- (cumsum(len))[val==T]


result <- rep(NA, length=length(example))

apply(ind, 1, function(x)
{
  if(any(example[x[1]:x[2]] < -1))
  {
    result[x[1]:x[2]] <- example[x[1]:x[2]]
   }    
})