我有一个表示时间序列的二进制向量。我想过滤出快速开关,如00000001100000000应为零,同样11111111111011111应该只是。
哪种过滤器/功能适合该任务?
答案 0 :(得分:2)
也许这是一种愚蠢的方法,但rle
/ inverse.rle
似乎是不错的候选人。例如。如果将快速开关定义为小于3个相等值的周期:
b1 <- c(rep(0, 7), rep(1, 2), rep(0, 7))
b2 <- c(rep(1, 10), 0, rep(1, 4))
binaryFilter <- function(x, threshold=3) {
r <- rle(x)
isBelowThreshold <- r$lengths < threshold
r$values[isBelowThreshold] <- abs(1-r$values[isBelowThreshold])
return(inverse.rle(r))
}
binaryFilter(b1)
# [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
binaryFilter(b2)
# [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
答案 1 :(得分:1)
如何使用加权平均值考虑邻近值?在这种情况下,考虑每个值的2个邻居(两侧都有2个邻居)。当然这可以调整。
> v <- sample(c(0,1),30,replace=TRUE)
> v
[1] 0 1 1 1 0 0 0 0 1 1 0 1 0 0 1 0 1 1 0 0 0 0 1 1 1 0 1 0 0 0
# embed(v,5) is a short version for this:
# cbind(v[1:26],v[2:27],v[3:28],v[4:29],v[5:30])
> m <- embed(v,5)
> c(round(m %*% c(.1,.2,.4,.2,.1)))
[1] 1 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0
before: 0 1 1 1 0 0 0 0 1 1 0 1 0 0 1 0 1 1 0 0 0 0 1 1 1 0 1 0 0 0
after: . . 1 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 . .
你可以看到,孤独者已经消失了。
根据sgibb的建议,整个模糊可以归结为:
round(filter(v, c(.1,.2,.4,.2,.1)))
(但我猜上面写出的版本清楚说明了做了什么,这就是为什么我离开它)
答案 2 :(得分:1)
另一种类似于@sgibb解决方案的解决方案,但使用rollapply
包中的zoo
。
更容易通过代码解释:)
filter_bin <-
function(vec,width =3){
trend <-
as.numeric(names(which.max(table(vec))))
rollapply(vec,width,function(x)
if(trend %in% x) trend else unique(x))
}
filter_bin(b2)
## 1 1 1 1 1 1 1 1 1 1 1 1 1
filter_bin(b1)
## 0 0 0 0 0 0 0 0 0 0 0 0 0 0