Как вставить все недостающие недели между новой и старой датой в таблицу данных для расчета недельного запаса R - PullRequest
0 голосов
/ 20 ноября 2018

Итак, у меня есть datatable df с идентификатором столбца DATE и STOCK

В этой таблице один и тот же идентификатор имеет несколько значений с их датой и запасом:

ID        DATE        STOCK
a1     2017-05-04       1
a1     2017-06-04       4
a1     2017-06-05       1
a1     2018-05-04       1
a1     2018-06-04       3
a1     2018-06-05       1
a2     2016-11-26       2
a2      ...             ..

Используя lubridate, я могуполучить, на какой неделе дата выглядит следующим образом:

dfWeeks=df[,"WEEK" := floor_date(df$`Date`, "week")]

ID        DATE        STOCK        WEEK
a1     2017-05-04       1       2017-04-30
a1     2017-06-04       4       2017-06-04
a1     2017-06-05       1       2017-06-04
a1     2018-05-04       1       2018-04-29
a1     2018-06-04       3       2018-06-03
a1     2018-06-05       1       2018-06-03
a2     2016-11-26       2       2016-11-20
a2      ...             ..

Итак, из столбца ДАТА я знаю, что моя старая дата 2017-05-04, а самая новая дата 2018-06-05, которая имеет около 56.71429 недель:

dates <- c( "2017-05-04","2018-06-05")
dif <- diff(as.numeric(strptime(dates, format = "%Y-%m-%d")))/(60 * 60 * 24 * 7) 

И в моей таблице всего 4 уникальных недели, поэтому идея состоит в том, чтобы суммировать запасы для каждой недели и вставлять недостающие (57-4 = 53 недели) со значением 0 в наличии.

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

meanStock<- dfWeeks[, .(mean=sum(Stock, na.rm = T)/dif <- diff(as.numeric(strptime(c(min(Date), max(Date)), format = "%Y-%m-%d")))/(60 * 60 * 24 * 7) ), by = .(ID)]

Но я не знаю, сработает ли это, надеюсь, я дал понять, и любые советы или подходы приветствуются.

ОБНОВЛЕНИЕ:

Вот так я получаю максимальную и минимальную дату

max = aggregate(df$`Date`,by=list(df$ID),max)
colnames(max) = c("ID", "MAX")
min = aggregate(df$`Date`,by=list(df$ID),min)
colnames(min) = c("ID", "MIN")
test <- merge(max, min, by="ID", all=T)

1 Ответ

0 голосов
/ 20 ноября 2018

Что-то вроде:

library(data.table)

setDT(df)[, DATE := as.Date(DATE)][, `:=` (st = min(DATE), end = max(DATE) + 7), by = ID][
  , .(ID = ID, DATE = DATE, STOCK = STOCK, Expanded = seq(st, end, by = "week")), by = 1:nrow(df)][
    , `:=` (WEEK = floor_date(Expanded, "week"), WEEK2 = floor_date(DATE, "week"))][
      WEEK != WEEK2, STOCK := 0][
        , .(SUM_STOCK = sum(STOCK)), by = .(WEEK, ID)]

Вывод (строки за недели от 2017-04-02 до 2017-06-11 и ID a1):

          WEEK ID SUM_STOCK
 1: 2017-04-02 a1         0
 2: 2017-04-09 a1         0
 3: 2017-04-16 a1         0
 4: 2017-04-23 a1         0
 5: 2017-04-30 a1         1
 6: 2017-05-07 a1         0
 7: 2017-05-14 a1         0
 8: 2017-05-21 a1         0
 9: 2017-05-28 a1         0
10: 2017-06-04 a1         5
11: 2017-06-11 a1         0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...