Ilya Vishnyakov
Ilya Vishnyakov

Reputation: 69

Apply function to sequence

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

Answers (2)

Florian
Florian

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

chinsoon12
chinsoon12

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

Related Questions