Разбейте стоимость по годам, а затем по месяцам по клиентам, проиндексировав строки - PullRequest
0 голосов
/ 15 марта 2019

У меня есть набор данных

dt <- data.table(Customer = c("a", "a", "c"), months = c(24, 12, 37), Date = c("2019-02-23","2019-03-31","2019-10-01"), Cost = c("100","200","370"))

Я хочу разбить затраты по годам и повторить клиента (по номеру строки)

months_to_year <- function(months){
  if(months%%12==0) y <- rep(12, months %/%  12) else y <- c(rep(12, months %/%  12), months %% 12)
  return(y)
}

dt$years<- dt$months/12
dt$Cost <- as.numeric(dt$Cost)
dt<- dt %>% mutate(Date = as.Date(Date), rn = row_number()) %>% 
  slice(rep(rn, ceiling(months/12)))%>%
  group_by(Customer, rn) %>%
  mutate(months1 = months_to_year(first(months)),
         Date = seq(first(Date), by="1 year", length.out=n()),
         Cost = Cost/months * months1)

Я получаю следующий вывод

  Customer months Date        Cost years    rn months1
  <chr>     <dbl> <date>     <dbl> <dbl> <int>   <dbl>
1 a            24 2019-02-23    50  2        1      12
2 a            24 2020-02-23    50  2        1      12
3 a            12 2019-03-31   200  1        2      12
4 c            37 2019-10-01   120  3.08     3      12
5 c            37 2020-10-01   120  3.08     3      12
6 c            37 2021-10-01   120  3.08     3      12
7 c            37 2022-10-01    10  3.08     3       1

Теперь я хочу дополнительно разбить его по месяцам

dt %>% mutate(Date = as.Date(Date), rn1 = row_number()) %>% 
  slice(rep(rn1, months1))%>%
  group_by(Customer, rn1) %>%
  mutate(New.Date = seq(first(Date), by="1 month", length.out=n()))

Однако клиент "a" в строке 3 индексируется как rn1 = 1, и новая дата начала1-месячный прирост по сравнению с предыдущим индексом rn = 1 для клиента "a".См. Новые строки столбцов даты 12 и 25 ... Я хочу получить новую дату в строке 25, чтобы начать 2019-03-31.

[![dt output][1]][1]

Буду очень признателен за любую помощь.

Спасибо.

1 Ответ

0 голосов
/ 15 марта 2019

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

library(data.table)

dt <- data.table(Customer = c("a", "a", "c"), months_num = c(24, 12, 37), Date = c("2019-02-23","2019-03-31","2019-10-01"), Cost = c(100,200,370))
#set dates
dt[, Date := as.POSIXct( Date, format = "%Y-%m-%d" ) ]
dt[, EndDate := Date %m+% months( months_num )][]

str(dt)
# Classes ‘data.table’ and 'data.frame':    3 obs. of  5 variables:
# $ Customer  : chr  "a" "a" "c"
# $ months_num: num  24 12 37
# $ Date      : POSIXct, format: "2019-02-23" "2019-03-31" "2019-10-01"
# $ Cost      : num  100 200 370
# $ EndDate   : POSIXct, format: "2021-02-23" "2020-03-31" "2022-11-01"

code

На самом деле однострочник, но разлитый по многострочным линиямдля читабельности на SO.

#monthly
dt[ , .( Customer = Customer, 
         month = seq(Date, 
                     by = "month", 
                     length.out = months_num ),
         Cost = Cost / months_num ), 
    by = .(id = 1:nrow(dt) )][]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...