Reputation: 69
I have a vector:
x <- c(1,2,3,4,5,6,7,8)
I need to calculate a vector, for example, with cumulative sum of squares:
y <- c(a1, a2, a3...)
where: a1 = 1^2
; a2 = 1^2+2^2
; a3 = 1^2 + 2^2 + 3^2
and so on.
It is like "cumsum", but I need to calculate my function (not only sum of sqares, but any) like this.
Thank you!
Upvotes: 2
Views: 2038
Reputation: 25385
First square the elements, than take the cumulative sum of that:
y <- cumsum(x^2)
Output:
1 5 14 30 55 91 140 204
For other functions such as ln(x1*x2*...xn)
, you can often still do them efficiently. If that is not possible, you could use sapply
, the following four are all equivalent in output:
log(cumprod(x))
sapply(cumprod(x), log)
sapply(cumprod(x), function(a) {log(a)})
sapply(1:8, function(i) {log(prod(x[1:i]))}) # not efficient.
However, note that the last one is computationally inefficient, since it calculates the product many times (first x1
, then x1*x2
, then x1*x2*x3
, then x1*x2*x3*x4
etc.), whereas the others use cumprod
, which calculates x1*x2
, and multiplies the output with x3
, multiplies that output with x4
, so the total number of multiplications is minimized. So always watch out that you are not over-complicating things.
Hope this helps!
Upvotes: 4
Reputation: 25225
There is a very nice reference on this by Hadley Wickham in Advanced R.
Below is a code example
func <- function(x, myfun, ...) {
cumsum(myfun(x, ...))
}
#examples
out <- func(1:8, `^`, e2=2)
identical(out, cumsum((1:8)^2))
identical(func(1:8, log), cumsum(log(1:8)))
Upvotes: 2