создание строк "за день" из выборочных фигур "за месяц" с использованием tidyverse - PullRequest
2 голосов
/ 26 июня 2019

У меня есть набор отчетов о продажах, содержащий магазины, которые сообщают данные о продажах «за день» или «за месяц». Когда я рисую их на одном графике, цифры «за месяц» выглядят как пики, что затрудняет понимание графика.

Я хочу преобразовать эти цифры "один раз в месяц", чтобы они равномерно распределялись по дням в месяце, чтобы я мог построить график ежедневных продаж.

Мне удалось использовать tidyverse, lubridate для вычисления столбца "sales_per_day" в наборах данных. Как я могу создать строки, которые "1 строка в день", т.е. для 2019-01 создать 30 ежедневных строк из каждой 1 строки ежемесячных данных?

sales <- tibble(
  distributor = c("StoreA", "StoreA", "StoreA", "StoreA", "StoreB"), 
  sales = c(100,200,300,400,5000), 
  date = c("2019-01-01", "2019-01-02", "2019-01-03", "2019-01-04", "2019-01-30"),
  freq = c("daily", "daily", "daily", "daily", "monthly"))

> sales
# A tibble: 5 x 4
  distributor sales date       freq   
  <chr>       <dbl> <chr>      <chr>  
1 StoreA        100 2019-01-01 daily  
2 StoreA        200 2019-01-02 daily  
3 StoreA        300 2019-01-03 daily  
4 StoreA        400 2019-01-04 daily  
5 StoreB       5000 2019-01-30 monthly


wanted_sales <- tibble(
  distributor = c("StoreA", "StoreA", "StoreA", "StoreA", "StoreB", "StoreB", "StoreB", "StoreB"), 
  sales = c(100, 200, 300, 400, 5000 / 30, 5000 / 30, 5000 / 30, 5000 / 30), 
  date = c("2019-01-01", "2019-01-02", "2019-01-03", "2019-01-04", "2019-01-01", "2019-01-02", "2019-01-03", "2019-01-04"),
  freq = c("daily", "daily", "daily", "daily", "daily", "daily", "daily", "daily" ))

> wanted_sales
# A tibble: 8 x 4
  distributor sales date       freq 
  <chr>       <dbl> <chr>      <chr>
1 StoreA       100  2019-01-01 daily
2 StoreA       200  2019-01-02 daily
3 StoreA       300  2019-01-03 daily
4 StoreA       400  2019-01-04 daily
5 StoreB       167. 2019-01-01 daily
6 StoreB       167. 2019-01-02 daily
7 StoreB       167. 2019-01-03 daily
8 StoreB       167. 2019-01-04 daily

per_day <- sales %>% filter(freq == "monthly") %>%
  group_by(date) %>%
  mutate(mdays = as.integer(days_in_month(as_date(date)))) %>%
  mutate(sales_per_day = sales / mdays)

> per_day
# A tibble: 1 x 6
# Groups:   date [1]
  distributor sales date       freq    mdays sales_per_day
  <chr>       <dbl> <chr>      <chr>   <int>         <dbl>
1 StoreB       5000 2019-01-30 monthly    31          161.

Я хочу сделать итоговый тиббл per_day с 30 строками, в котором столбец $ date представляет собой последовательность "2019-01-01", "2019-01-02" ... "2019-01-30".

1 Ответ

2 голосов
/ 26 июня 2019

Мы можем изменить date на фактический класс Date и создать новый столбец startdate, который будет иметь первый день этого конкретного месяца, если freq не равен "daily" и sales делится на 30. Длякаждый date мы используем complete, чтобы создать последовательность дат и изменить freq на "daily" для всех.

library(dplyr)
library(tidyr)
library(lubridate)

sales %>%
  mutate(date = as.Date(date), 
         startdate = if_else(freq == "daily", date, floor_date(date, "month")), 
         sales = if_else(freq == "daily", sales, sales/30)) %>%
   group_by(date) %>%
   complete(date = seq(startdate, date, "1 day"), sales = sales, 
            freq = "daily", distributor = distributor) %>%
   select(-startdate)

# Groups:   date [30]
#   date       sales freq  distributor
#   <date>     <dbl> <chr> <chr>      
# 1 2019-01-01  100  daily StoreA     
# 2 2019-01-02  200  daily StoreA     
# 3 2019-01-03  300  daily StoreA     
# 4 2019-01-04  400  daily StoreA     
# 5 2019-01-01  167. daily StoreB     
# 6 2019-01-02  167. daily StoreB     
# 7 2019-01-03  167. daily StoreB     
# 8 2019-01-04  167. daily StoreB     
# 9 2019-01-05  167. daily StoreB     
#10 2019-01-06  167. daily StoreB     
# … with 25 more rows
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...