Приведенные данные вымышлены, а в реальности они сложнее
t <- data.frame(v1=c(265, -268, 123, 58, 560, 56, -260, 40, 530, -895, 20))
Я хочу подсчитать совокупную сумму с двумя предельными значениями: 0 и 500. Если кумулятивный итог превышает 500, вы должны оставить 500. Если кумулятивный итог станет отрицательным, вы должны сохранить 0 . Получены следующие результаты:
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
Формула в excel будет такой: =если(B1+A2<0; 0; если(B1+A2>500; 500; B1+A2))
Есть идеи?
Мы можем использовать min
и max
для установки границ и Reduce
для итерации вектора.
> 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
Используя Rcpp
(базовый код из здесь):
library(Rcpp)
cppFunction('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 < 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.
Взяв за основу идею @ThomasIsCoding, вот аккуратный подход:
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
@GrBa. Спасибо, что приняли ответ. Но вы должны принять ответ ThomasIsCoding, потому что происхождение находится в его ответе. У меня просто незначительная адаптация! Большое спасибо!
Я долго думал, какой ответ отметить. Но ваш ответ более полный. Надеюсь, ThomasIsCoding поймет мой поступок.
Есть ли для этого решение на основе
dplyr
? 🤔