R Studio - получите суммирование за прошедший месяц - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть фрейм данных, как показано ниже, и я хочу получить сумму (значение) для каждого 4 скользящего месяца.

Редактировать: На выходе у меня "2018-12". Но это не показано на входе. Это опечатка, мои фактические данные содержат «2018-12».

enter image description here

Я предпочитаю использовать dplyr:

group <- c("red","green","red","red","red","green","green","green","red","green","green","green")
Month <- c("2019-01","2019-02","2019-03","2019-03","2019-05","2019-07","2019-07","2019-08","2019-09","2019-10","2019-10","2019-10")
VALUE <- c(10,20,30,40,50,60,70,80,90,100,110,120)
d_f <- data.frame(group,Month,VALUE)

d_f %>%
  group_by(group) %>%
  summarise(value = sum(value))

Может кто-нибудь, пожалуйста, помогите мне, как справиться с 4 месяцами прокатки? Большое спасибо за ваше драгоценное время.

Ответы [ 2 ]

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

Используя lubridate, вы можете использовать floor_date и группировать даты по 4-месячным интервалам.

library(tidyverse)
library(lubridate)

d_f %>%
  mutate(date = as.Date(paste0(Month, '-01'), format = "%Y-%m-%d")) %>%
  arrange(date) %>%
  group_by(group, startdategroup = floor_date(date, "4 months")) %>%
  summarise(value = sum(VALUE)) %>%
  mutate(enddategroup = startdategroup %m+% months(4) - 1)

Вывод

# A tibble: 6 x 4
# Groups:   group [2]
  group startdategroup value enddategroup
  <fct> <date>         <dbl> <date>      
1 green 2019-01-01        20 2019-04-30  
2 green 2019-05-01       210 2019-08-31  
3 green 2019-09-01       330 2019-12-31  
4 red   2019-01-01        80 2019-04-30  
5 red   2019-05-01        50 2019-08-31  
6 red   2019-09-01        90 2019-12-31 

Редактировать : чтобы разрешить "перекрывающийся месяц" (месяцы на границе двух последовательных интервалов дат), я мог бы использовать другой подход.

Во-первых, я мог бы создать последовательность дат начала и окончания для интервалов (на основе минимальных и максимальных дат в вашем фрейме данных). Последовательность будет иметь интервалы дат каждые 4 месяца.

Затем я сделаю fuzzy_left_join (используя >= и <= logi c) и объединю этот новый фрейм данных с вашим. Затем строка данных за один месяц может быть подсчитана дважды (один раз для каждого из двух различных интервалов).

library(fuzzyjoin)

d_f$date = as.Date(paste0(Month, '-01'), format = "%Y-%m-%d")

d_f2 <- data.frame(date_start = seq.Date(min(d_f$date), max(d_f$date), "4 months"))
d_f2$date_end = date_start %m+% months(4)

d_f %>%
  fuzzy_left_join(d_f2, 
                  by = c("date" = "date_start", "date" = "date_end"), 
                  match_fun = list(`>=`, `<=`)) %>%
  group_by(group, date_start, date_end) %>%
  summarise(value = sum(VALUE))

Выход

# A tibble: 6 x 4
# Groups:   group, date_start [6]
  group date_start date_end   value
  <fct> <date>     <date>     <dbl>
1 green 2019-01-01 2019-05-01    20
2 green 2019-05-01 2019-09-01   210
3 green 2019-09-01 2020-01-01   330
4 red   2019-01-01 2019-05-01   130
5 red   2019-05-01 2019-09-01   140
6 red   2019-09-01 2020-01-01    90
0 голосов
/ 24 апреля 2020

Одним из подходов является использование функций lag / lead в dplyr. Что-то вроде:

df2 = df %>%
  group_by(group) %>%
  mutate(prev_value = lag(value, 1, order_by = month),
         prev_value2 = lag(value, 2, order_by = month),
         prev_value3 = lag(value, 3, order_by = month)) %>%
  mutate(avg = (value + prev_value + prev_value2 + prev_value3) / 4)

А затем отфильтруйте интервалы, которые вас не интересуют.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...