在r中的某个阈值处断开cumsum()函数

时间:2017-02-19 15:17:45

标签: r cumsum

例如,我有以下代码:

for j=1:size(chaining,2)
    for k=1:size(chaining,2)
        result(j,k) = sum(chaining{1,:}(j,k));
    end
end

如果元素i + 1大于chaining{1,:},我想打破它。我怎么能这样做?

所以不是这个结果:

cumsum(1:100)

我想得到以下结果:

3000

2 个答案:

答案 0 :(得分:4)

正如我在评论中所提到的,即使像我这样的人,在Rcpp中写一些简单的东西应该不是什么大问题。这是一个非常原始的实现,似乎有效(感谢@ MatthewLundberg的改进建议)

library(Rcpp)
cppFunction('NumericVector cumsumCPP(NumericVector x, int y = 0){

    // y = 0 is the default
    // Need to do this in order to avoid modifying the original x
    int n = x.size();
    NumericVector res(n);
    res[0] = x[0];

    for (int i = 1 ; i < n ; i++) {
      res[i] = res[i - 1] + x[i];
      if (res[i] > y && (y != 0)) { 
        // This breaks the loop if condition met
        return res[seq(0, i - 1)];
      }
    }

    // This handles cases when y== 0 OR y != 0 and y > cumsum(res)
    return res;
}')

cumsumCPP(1:100, 3000)
#  [1]    1    3    6   10   15   21   28   36   45   55   66   78   91  105  120  136  153  171  190  210  231  253  276  300
# [25]  325  351  378  406  435  465  496  528  561  595  630  666  703  741  780  820  861  903  946  990 1035 1081 1128 1176
# [49] 1225 1275 1326 1378 1431 1485 1540 1596 1653 1711 1770 1830 1891 1953 2016 2080 2145 2211 2278 2346 2415 2485 2556 2628
# [73] 2701 2775 2850 2926

与基础R cumsum类似,这适用于整数和浮点数,并且不处理NA。 treshhold的默认值设置为0 - 如果你想限制一个负cumsum,这是不理想的,但我现在想不出任何更好的价值(你可以决定一个自己)。

虽然可以使用一些优化......

set.seed(123)
x <- as.numeric(sample(1:1e3, 1e7, replace = TRUE))
microbenchmark::microbenchmark(cumsum(x), cumsumCPP(x))
# Unit: milliseconds
#         expr      min        lq      mean   median        uq       max neval cld
#    cumsum(x) 58.61942  61.46836  72.50915  76.7568  80.97435  99.01264   100  a 
# cumsumCPP(x) 98.44499 100.09979 110.45626 112.1552 119.22958 131.97619   100   b

identical(cumsum(x), cumsumCPP(x))
## [1] TRUE

答案 1 :(得分:1)

我们可以在<=输出

上使用cumsum
v1[v1 <=3000]

或另一种选择是

setdiff(pmin(cumsum(1:100), 3000), 3000)

,其中

v1 <- cumsum(1:100)
相关问题