Eric
Eric

Reputation: 1389

serially subtract from vector elements

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

Answers (1)

josliber
josliber

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

Related Questions