Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A iterative and lagging function similar to diff in R, but not just difference?

Tags:

r

The diff function in R returns suitably lagged and iterated differences.

x = c(1, 2, 1, 3, 11, 7, 5)
diff(x)
# [1]  1 -1  2  8 -4 -2
diff(x, lag=2)
[1]  0  1 10  4 -6

Is there anyway to customize this so that we can use functions other than difference? For example, sum:

itersum(x)
# 3 3 4 14 18 12
like image 730
qed Avatar asked Jul 28 '13 14:07

qed


People also ask

What is the diff function in R?

diff() function in R Language is used to find the difference between each consecutive pair of elements of a vector.

What is a lagged difference?

a numeric vector or matrix containing the values to be differenced. an integer indicating which lag to use. an integer indicating the order of the difference.

How do I compare data in R?

In R, the difference operator for xts is made available using the diff() command. This function takes two arguments of note. The first is the lag , which is the number of periods, and the second is differences , which is the order of the difference (e.g. how many times diff() is called).


2 Answers

In base R, there is the filter function. It is not as friendly and general as zoo::rollapply but it is extremely fast. In your case, you are looking to apply a convolution filter with weights c(1, 1):

itersum <- function(x, n = 2) tail(filter(x, rep(1, n)), sides = 1), -(n-1))

itersum(x)
# 3 3 4 14 18 12

To give you more ideas, here is how the diff and cumsum functions can be re-written in terms of filter:

diff   <- function(x) head(filter(x, c(1, -1)), -1)
cumsum <- function(x) filter(x, 1, method = "recursive")

In general, if you are looking to roll a binary function, then head and tail is probably the easiest and fastest way to go as it will take advantage of vectorized functions:

itersum     <- function(x) tail(x, -1) + head(x, -1)
diff        <- function(x) tail(x, -1) - head(x, -1)
sign.change <- function(x) tail(sign(x), -1) != head(sign(x), -1)
like image 54
flodel Avatar answered Sep 24 '22 23:09

flodel


You can use zoo::rollapply

require(zoo)
x <- c(1, 2, 1, 3, 11, 7, 5)
rollapply(x, width = 2, FUN = sum)
## [1]  3  3  4 14 18 12
like image 23
dickoa Avatar answered Sep 23 '22 23:09

dickoa