R 有界累积和?

R 有界累积和?,r,R,如何对向量进行累积求和(如cumsum),但要有界,使求和永远不会低于下限或高于上限 标准cumsum函数将产生以下结果 foo <- c(100, -200, 400, 200) cumsum(foo) # [1] 100 -100 300 500 cumsum.bounded(foo, lower.bound = 0, upper.bound = 500) # [1] 100 0 400 500 谢谢如评论中所述,Rcpp是一个好方法 cumsumBounded.cp

如何对向量进行累积求和(如
cumsum
),但要有界,使求和永远不会低于下限或高于上限

标准cumsum函数将产生以下结果

foo <- c(100, -200, 400, 200)
cumsum(foo)
# [1]  100 -100  300  500
cumsum.bounded(foo, lower.bound = 0, upper.bound = 500)
# [1]  100  0  400  500

谢谢

如评论中所述,
Rcpp
是一个好方法

cumsumBounded.cpp

#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]                                                             
NumericVector cumsumBounded(NumericVector x, double low, double high) {
  NumericVector res(x.size());
  double acc = 0;
  for (int i=0; i < x.size(); ++i) {
    acc += x[i];
    if (acc < low)  acc = low;
    else if (acc > high)  acc = high;
    res[i] = acc;
  }
  return res;
}
#包括
使用名称空间Rcpp;
//[[Rcpp::导出]]
数值向量cumsumBounded(数值向量x,双低,双高){
数值向量res(x.size());
双acc=0;
对于(int i=0;i高)acc=高;
res[i]=acc;
}
返回res;
}
编译并使用新函数:

library(Rcpp)
sourceCpp(file="cumsumBounded.cpp")
foo <- c(100, -200, 400, 200)
cumsumBounded(foo, 0, 500)
# [1] 100   0 400 500
库(Rcpp)
sourceCpp(file=“cumsumBounded.cpp”)

foo这里有几个纯R版本。不太可能像使用C/C++那样快,但其中一个可能足够快,可以满足您的需要,并且更易于维护:

# 1 Reduce
cumsum.bounded <- function(x, lower.bound = 0, upper.bound = 500) {
    bsum <- function(x, y) min(upper.bound, max(lower.bound, x+y))
    if (length(x) > 1) Reduce(bsum, x, acc = TRUE) else x
}

# 2 for loop
cumsum.bounded2 <- function(x, lower.bound = 0, upper.bound = 500) {
   if (length(x) > 1) 
      for(i in  2:length(x)) x[i] <- min(upper.bound, max(lower.bound, x[i] + x[i-1]))
   x
}
#1减少

cumsum.bounded我想这可能行得通

library ("Rcpp")

cumsum.bounded <- cppFunction(
    'NumericVector cumsum_bounded (NumericVector x, const double lower, const double upper) {

        double acc = 0;
        NumericVector result(x.size());

        for(int i = 0; i < x.size(); i++) {
            acc += x[i];

            if (acc < lower) acc = lower;
            if (acc > upper) acc = upper;

            result[i] = acc;
        }

        return result;
    }')
库(“Rcpp”)

cumsum.bounded如果您正在寻找一个与基本
cumsum
函数一样高效的函数,您必须在
C
中实现它。根据您的需要调整Rcpp的sugar函数应该相对容易。据我所知,您只需要添加一条if语句。@SvenHohenstein或更可能的是
Rcpp
解决方案。如果第一个元素打破了界限,它们就会失败<代码>累计有界(c(-1,-1,3,4,5),0,10)=>1 0 3 7 10
累计有界(c(20,-1,3,4,5),0,10)=>20 10
存在这样的问题,例如边大小写是否真的是问题的一部分,或者问题是否要将和保持在边界内,但如果需要,可以使用
cumsum.bounded(c(0,x),0,10)[-1]轻松处理
或在函数中单独处理初始值。是的,当然。我觉得这仍然值得注意。我用它来计算某种偏好,其中我对匹配谓词的选择有一个1,如果不匹配,则为-1。对于一些谓词来说,第一个选择是错误的,这导致我产生了奇怪的情节。如果您意识到了这一点,那么很容易首先清理数据。