我有一个逻辑向量
v <- c(FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE)
我想计算每个FALSE
之间TRUE
的数量。对于上面的例子,期望的结果是
3 2 1 4
理想情况下,答案不会使用迭代方法。我的实际应用是一个更大的逻辑向量。效率越高越好。
谢谢!
答案 0 :(得分:5)
您可以使用rle
功能,例如:
out <- rle(v)
out$lengths[!out$values]
# [1] 3 2 1 4
与with
功能相关联:
with(out, lengths[!values])
# [1] 3 2 1 4
答案 1 :(得分:5)
diff(which(c(TRUE, v))) - 1
如果你追求效率。
答案 2 :(得分:2)
虽然问题已经解决,但这里有一个C ++函数,它会进一步提升它,虽然写起来有点麻烦。
require(Rcpp)
require(inline)
cpp.fun <- cxxfunction(signature(x="logical"), plugin="Rcpp", body='
int n = LENGTH(x);
Rcpp::IntegerVector lengths(n);
int count = 0;
for(int i = 0; i < n; i++){
if(!LOGICAL(x)[i]){
lengths[count]++;
} else {
count++;
}
}
lengths = Rcpp::head(lengths, count);
return(lengths);
')
v <- runif(10000000) > .8
require(microbenchmark)
microbenchmark(a = with(rle(v), lengths[!values]),
b = diff(which(c(TRUE, v))) - 1,
c = cpp.fun(v))
Unit: milliseconds
expr min lq mean median uq max neval
a 479.59042 543.26234 585.36910 558.24042 605.80794 863.5284 100
b 75.82237 81.25428 103.31213 87.55149 131.09488 219.2535 100
c 42.01732 44.69037 50.14274 45.80284 47.67927 102.3952 100