самостоятельное присоединение для добавления значений предыдущего месяца - PullRequest
0 голосов
/ 03 апреля 2020

Это моя неуклюжая попытка самостоятельно присоединиться к фрейму данных временного ряда и добавить столбец предыдущего месяца:

df <- data.frame(
    date = c(
        as.Date("2015-1-1")
        , as.Date("2015-2-1")
        , as.Date("2015-3-1")
        , as.Date("2015-4-1")
        , as.Date("2015-5-1")
        , as.Date("2015-6-1")
        , as.Date("2015-7-1")
        , as.Date("2015-8-1")
        , as.Date("2015-9-1")
        , as.Date("2015-10-1")
        , as.Date("2015-11-1")
        , as.Date("2015-12-1")
    )
    ,value = c(1,2,3,4,5,6,7,8,9,10,11,12)
) %>%
    mutate(
        previous_month = date %m+% months(-1)
    )

temp <- df %>%
    left_join(df, by = c("previous_month" = "date")) %>%
    mutate(
        value.y = ifelse(is.na(value.y), 0, value.y)
    )
temp

Есть ли более простой способ сделать это (за n предыдущих месяцев), а также управлять именованием созданных столбцов значений (например, value.y)? Спасибо!

PS:

Это вариант - см. Принятый ответ.

df <- data.frame(
    date = c(
        as.Date("2015-1-1")
        , as.Date("2015-2-1")
        , as.Date("2015-3-1")
        , as.Date("2015-4-1")
        , as.Date("2015-5-1")
        , as.Date("2015-6-1")
        , as.Date("2015-7-1")
        , as.Date("2015-8-1")
        , as.Date("2015-9-1")
        , as.Date("2015-10-1")
        , as.Date("2015-11-1")
        , as.Date("2015-12-1")
    )
    ,value = c(1,2,3,4,5,6,7,8,9,10,11,12)
) %>%
mutate(
    month_minus_1 = lag(value, n=1)
    , month_minus_2 = lag(value, n=2)
    , month_minus_3 = lag(value, n=3)
    , month_minus_4 = lag(value, n=4)
    , month_minus_5 = lag(value, n=5)
    , month_minus_6 = lag(value, n=6)
)

df

Ответы [ 2 ]

1 голос
/ 03 апреля 2020

Как уже отмечалось, lag() - это функция, которую вы ищете, но если вы хотите применить ее несколько раз или неопределенное количество раз, это может стать проблемой c, так как мы должны были бы создать и назвать каждый столбец.

Используя mutate_at, мы можем применить несколько функций к одному и тому же (или несколько столбцов). Поэтому нам нужно создать список функций, которые выполняют ту работу, которую мы хотим:

lags_list <- 1:3 %>% 
  map(~partial(lag, n=.x, default=0)) %>% 
  set_names(paste0('lag', 1:3))

lag_list теперь список функций в форме lag(x, n=1, default=0), где n изменяется для каждого элемента list.

Теперь мы можем просто применить к нашему столбцу:

library(dplyr)
library(purrr)

lags_list <- 1:3 %>% 
  map(~partial(lag, n=.x, default=0)) %>% 
  set_names(paste0('lag', 1:3))


df %>% 
  mutate_at(vars(value), lags_list)
#>          date value lag1 lag2 lag3
#> 1  2015-01-01     1    0    0    0
#> 2  2015-02-01     2    1    0    0
#> 3  2015-03-01     3    2    1    0
#> 4  2015-04-01     4    3    2    1
#> 5  2015-05-01     5    4    3    2
#> 6  2015-06-01     6    5    4    3
#> 7  2015-07-01     7    6    5    4
#> 8  2015-08-01     8    7    6    5
#> 9  2015-09-01     9    8    7    6
#> 10 2015-10-01    10    9    8    7
#> 11 2015-11-01    11   10    9    8
#> 12 2015-12-01    12   11   10    9

Мы также можем создать функцию для более элегантного выполнения:

add_lags <- function(data, col, n) {
  lags_list <- 1:n %>% 
    map(~partial(lag, n=.x, default=0)) %>% 
    set_names(paste0('lag', 1:n))

  data %>% 
    mutate_at(vars({{col}}), lags_list)
}

df %>% add_lags(value, n=5)
#>          date value lag1 lag2 lag3 lag4 lag5
#> 1  2015-01-01     1    0    0    0    0    0
#> 2  2015-02-01     2    1    0    0    0    0
#> 3  2015-03-01     3    2    1    0    0    0
#> 4  2015-04-01     4    3    2    1    0    0
#> 5  2015-05-01     5    4    3    2    1    0
#> 6  2015-06-01     6    5    4    3    2    1
#> 7  2015-07-01     7    6    5    4    3    2
#> 8  2015-08-01     8    7    6    5    4    3
#> 9  2015-09-01     9    8    7    6    5    4
#> 10 2015-10-01    10    9    8    7    6    5
#> 11 2015-11-01    11   10    9    8    7    6
#> 12 2015-12-01    12   11   10    9    8    7

Создано в 2020-04-03 пакетом представ (v0.3.0)

(Используя ваши данные:)

df <- data.frame(
  date = c(
    as.Date("2015-1-1")
    , as.Date("2015-2-1")
    , as.Date("2015-3-1")
    , as.Date("2015-4-1")
    , as.Date("2015-5-1")
    , as.Date("2015-6-1")
    , as.Date("2015-7-1")
    , as.Date("2015-8-1")
    , as.Date("2015-9-1")
    , as.Date("2015-10-1")
    , as.Date("2015-11-1")
    , as.Date("2015-12-1")
  )
  ,value = c(1,2,3,4,5,6,7,8,9,10,11,12)
)
1 голос
/ 03 апреля 2020

Возможно, вы могли бы использовать функцию lag из dplyr. Что бы вы хотели в качестве значения для первого previous_month столбца? Здесь я сохранил это NA. Вы также можете создать столбец previous_month так, как вы это сделали, и использовать lag только для столбца previous_value.

df %>% 
  mutate(previous_month = lag(date),
         previous_value = lag(value,default =  0))

1  2015-01-01     1           <NA>              0
2  2015-02-01     2     2015-01-01              1
3  2015-03-01     3     2015-02-01              2
4  2015-04-01     4     2015-03-01              3
5  2015-05-01     5     2015-04-01              4
6  2015-06-01     6     2015-05-01              5
7  2015-07-01     7     2015-06-01              6
8  2015-08-01     8     2015-07-01              7
9  2015-09-01     9     2015-08-01              8
10 2015-10-01    10     2015-09-01              9
11 2015-11-01    11     2015-10-01             10
12 2015-12-01    12     2015-11-01             11
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...