对于时间序列分析,我处理的数据通常包含前导和尾随零元素。在此示例中,在开头有3个零,在结尾有2个。我想摆脱这些元素,并过滤掉中间的内容(也可能包含零)
vec <- c(0, 0, 0, 1, 2, 0, 3, 4, 0, 0)
我这样做是通过从头到尾循环,并屏蔽掉不需要的元素。
mask <- rep(TRUE, length(vec))
# from begin
i <- 1
while(vec[i] == 0 && i <= length(vec)) {
mask[i] <- FALSE
i <- i+1
}
# from end
i <- length(vec)
while(i >= 1 && vec[i] == 0) {
mask[i] <- FALSE
i <- i-1
}
cleanvec <- vec[mask]
cleanvec
[1] 1 2 0 3 4
这行得通,但我想知道是否有更有效的方法来避免循环。
答案 0 :(得分:6)
vec[ min(which(vec != 0)) : max(which(vec != 0)) ]
基本上which(vec != 0)
部分给出了不同于0的数字的位置,然后取它们的 min 和 max 。
答案 1 :(得分:0)
我们可以使用range
和Reduce
来获取序列
vec[Reduce(`:`, range(which(vec != 0)))]
#[1] 1 2 0 3 4
答案 2 :(得分:0)
将cumsum
的{{1}}向前和向后移动,并仅保留> 0的元素。如果已知abs(vec)
的所有元素均为非负数(如问题所示),则我们可以选择省略vec
。
abs