Как реализовать скользящее / запаздывающее окно? - PullRequest
0 голосов
/ 21 марта 2019

Итак, я использовал zoo::rollapply() довольно религиозно, но я не думаю, что это подходит для рассматриваемой проблемы.У меня есть требование, в котором я хотел бы реализовать усадку скользящего окна.Так, например, вот некоторые примеры данных:

v <- data.frame(date=as.Date("2012-1-2") + 0:4, vals=c(1,2,3,4,5))
v
        date vals
1 2012-01-02    1
2 2012-01-03    2
3 2012-01-04    3
4 2012-01-05    4
5 2012-01-06    5

Я бы хотел, чтобы скользящее окно перемещалось в порядке убывания даты, поэтому rev(v$date) для заказа, и я хотел бы суммировать значения следующим образом [lagging by1 каждое окно] (каждая строка ниже является окном):

5 + 4 + 3 + 2 + 1 = 15
    4 + 3 + 2 + 1 = 10
        3 + 2 + 1 = 6
            2 + 1 = 3
                1 = 1

, поэтому я ожидаю, что мой data.frame будет:

#        date vals new_val
#1 2012-01-02    1       1
#2 2012-01-03    2       3
#3 2012-01-04    3       6
#4 2012-01-05    4      10
#5 2012-01-06    5      15

ПРИМЕЧАНИЕ. Скажем так:В примере используется функция sum(x) для вычисления каждого окна.Было бы здорово обобщить это на любой function(x).Допустим, function(x) { (min(x) + max(x)) * length(x) * sum(x) }

ПРИМЕЧАНИЕ. Я бы предпочел реализацию base R, но другие пакеты, которые могли бы быть применимы, также были бы интересны

Ответы [ 3 ]

3 голосов
/ 21 марта 2019

Попробуйте

v$new_val <- cumsum(v$vals)
v
#        date vals new_val
#1 2012-01-02    1       1
#2 2012-01-03    2       3
#3 2012-01-04    3       6
#4 2012-01-05    4      10
#5 2012-01-06    5      15
1 голос
/ 21 марта 2019

Используйте cumsum и rev следующим образом:

transform(v, sum = rev(cumsum(vals)))

, давая:

        date vals sum
1 2012-01-02    1  15
2 2012-01-03    2  10
3 2012-01-04    3   6
4 2012-01-05    4   3
5 2012-01-06    5   1

или отмечая, что аргумент width может быть вектором (см. ?rollapply):

library(zoo)

transform(v, sum = rev(rollapplyr(vals, seq_along(vals), sum)))
1 голос
/ 21 марта 2019

Вот один, использующий sapply

v <- data.frame(date=as.Date("2012-1-2") + 0:4, vals=c(1,2,3,4,5))

v <- data.frame(v[order(rev(v$date)), ],
                  "new_val" = sapply(1:nrow(v), function(x) sum(v[order(rev(v$date)), "vals"][x:5])))

> v
        date vals new_val
5 2012-01-06    5      15
4 2012-01-05    4      10
3 2012-01-04    3       6
2 2012-01-03    2       3
1 2012-01-02    1       1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...