Reputation: 1389
I need to subtract a number from a vector in such a way that it is subtracted serially from the elements. As an example, consider the vector a = c(8, 4)
. If I want to serially subtract 9 from this vector, I first subtract 9 from the first vector element, 8. That leaves 0 for the first element with a reminder of 1, that then gets subtracted from the second element. That leaves 4-1=3 for the second vector element.
I can do this with a bunch of inelegant if-else statement. There must be a better way. It would be easier to show examples:
I assume that the serial subtraction function is called serialSub.
a = c(8,4)
serialSub(a,4)
> [1] 4 4
serialSub(a,8)
> [1] 0 4
serialSub(a,9)
> [1] 0 3
serialSub(a,13)
> [1] 0 0
serialSub(a,0)
> [1] 8 4
Upvotes: 3
Views: 303
Reputation: 44309
If tosub
is the total amount to subtract away, then pmin(cumsum(a), tosub)
is the total amount that should be removed from each element of the cumulative sum of a
, and therefore cumsum(a) - pmin(cumsum(a), tosub)
is the cumulative sum of our new vector. We need to obtain the vector that gives this cumulative sum, which can be done using diff
:
a <- c(8, 4)
serialSub <- function(a, tosub) diff(c(0, cumsum(a) - pmin(cumsum(a), tosub)))
serialSub(a,4)
# [1] 4 4
serialSub(a,8)
# [1] 0 4
serialSub(a,9)
# [1] 0 3
serialSub(a,13)
# [1] 0 0
serialSub(a,0)
# [1] 8 4
Upvotes: 6