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

前端 未结 3 1271
情书的邮戳
情书的邮戳 2021-02-10 06:11

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          


        
相关标签:
3条回答
  • 2021-02-10 06:18

    For the record, I asked this question to figure out how to register sign changes in a vector of numbers, thanks to @dickoa 's answer, I got it done this way:

    require(zoo)
    equals = function(x) all(diff(x) == 0)
    x = c(2, 3, -1, 3, -2, -5)
    y = sign(x)
    rollapply(y, 2, equals)
    [1]  TRUE FALSE FALSE FALSE  TRUE
    
    0 讨论(0)
  • 2021-02-10 06:24

    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
    
    0 讨论(0)
  • 2021-02-10 06:35

    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)
    
    0 讨论(0)
提交回复
热议问题