累积和,带有两个条件。

huangapple go评论59阅读模式
英文:

cumulative sum with two conditions

问题

The given data are fictitious, and in reality they are more complicated

t <- data.frame(v1=c(265, -268, 123, 58, 560, 56, -260, 40, 530, -895, 20))

I want to count a cumulative sum with two limiting values: 0 and 500. If the cumulative total exceeds 500 then you must keep 500. If the cumulative total becomes negative then you must store 0.

The formula in excel would be like this:
=if(B1+A2<0; 0; if(B1+A2>500; 500; B1+A2))

英文:

The given data are fictitious, and in reality they are more complicated

t &lt;- data.frame(v1=c(265, -268, 123, 58, 560, 56, -260, 40, 530, -895, 20))

I want to count a cumulative sum with two limiting values: 0 and 500.
If the cumulative total exceeds 500 then you must keep 500. If the cumulative total becomes negative then you must store 0 .
The results obtained are as follows:

     v1 sum.c
1   265   265
2  -268     0
3   123   123
4    58   181
5   560   500
6    56   500
7  -260   240
8    40   280
9   530   500
10 -895     0
11   20    20

The formula in excel would be like this:
=if(B1+A2<0; 0; if(B1+A2>500; 500; B1+A2))

Any ideas?

答案1

得分: 6

We can use min and max to set the boundaries and Reduce to iterate the vector

> v1 <- c(265, -268, 123, 58, 560, 56, -260, 40, 530, -895, 20)

> Reduce(function(x, y) min(max(x + y, 0), 500), v1, accumulate = TRUE)
 [1] 265   0 123 181 500 500 240 280 500   0  20

我们可以使用 minmax 来设置边界,使用 Reduce 来迭代向量。

英文:

We can use min and max to set the boundaries and Reduce to iterate the vector

&gt; v1 &lt;- c(265, -268, 123, 58, 560, 56, -260, 40, 530, -895, 20)

&gt; Reduce(function(x, y) min(max(x + y, 0), 500),v1, accumulate = TRUE)
 [1] 265   0 123 181 500 500 240 280 500   0  20

答案2

得分: 3

Using Rcpp(基本代码来自此处):

library(Rcpp)
cppFunction('NumericVector cumsumCPP(NumericVector x){

    // 为了避免修改原始 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] > 500) { 
        res[i] = 500;
      }
      if (res[i] < 0) {
        res[i] = 0;
      }
    }

    return res;
}')

cumsumCPP(t$v1)
[1] 265   0 123 181 500 500 240 280 500   0  20

library(dplyr)
t %>% mutate(cum_s = cumsumCPP(v1))

     v1 cum_s
1   265   265
2  -268     0
3   123   123
4    58   181
5   560   500
6    56   500
7  -260   240
8    40   280
9   530   500
10 -895     0
11   20    20

您还可以在 R 中自定义累积和函数。

英文:

Using Rcpp (Base code from here):

library(Rcpp)
cppFunction(&#39;NumericVector cumsumCPP(NumericVector x){

    // 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 &lt; n ; i++) {
      res[i] = res[i - 1] + x[i];
      if (res[i] &gt; 500) { 
        res[i] = 500;
      }
      if (res[i] &lt; 0) {
        res[i] = 0;
      }
    }

    return res;
}&#39;)

cumsumCPP(t$v1)
[1] 265   0 123 181 500 500 240 280 500   0  20

library(dplyr)
t%&gt;%mutate(cum_s=cumsumCPP(v1))

     v1 cum_s
1   265   265
2  -268     0
3   123   123
4    58   181
5   560   500
6    56   500
7  -260   240
8    40   280
9   530   500
10 -895     0
11   20    20

You can also define your own customize cumulative sum in R.

答案3

得分: 3

Here is the translated code portion:

从 @ThomasIsCoding 处借鉴的思路,这是 tidyverse 的方法:

library(dplyr)
library(purrr)

t %>%
mutate(sum.c = accumulate(v1, ~ min(max(.x + .y, 0), 500)))

 v1 sum.c

1 265 265
2 -268 0
3 123 123
4 58 181
5 560 500
6 56 500
7 -260 240
8 40 280
9 530 500
10 -895 0
11 20 20

英文:

Taking the idea from @ThomasIsCoding, here is tidyverse approach:

library(dplyr)
library(purrr)

t %&gt;%
  mutate(sum.c = accumulate(v1, ~ min(max(.x + .y, 0), 500)))

     v1 sum.c
1   265   265
2  -268     0
3   123   123
4    58   181
5   560   500
6    56   500
7  -260   240
8    40   280
9   530   500
10 -895     0
11   20    20

huangapple
  • 本文由 发表于 2023年4月11日 03:09:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75979978.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定