Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

serially subtract from vector elements

Tags:

r

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
like image 944
Eric Avatar asked Dec 02 '25 08:12

Eric


1 Answers

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
like image 104
josliber Avatar answered Dec 04 '25 20:12

josliber