在'TRUE`

时间:2015-08-06 06:35:39

标签: r

我有一个逻辑向量

v <- c(FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE)

我想计算每个FALSE之间TRUE的数量。对于上面的例子,期望的结果是

3 2 1 4

理想情况下,答案不会使用迭代方法。我的实际应用是一个更大的逻辑向量。效率越高越好。

谢谢!

3 个答案:

答案 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