Заполнение столбца фрейма данных четвертными датами окончания (R) - PullRequest
0 голосов
/ 01 апреля 2020

Я пытаюсь получить столбец моего фрейма данных (ValuationDate), отражающий даты «конца квартала» (31 декабря, 31 марта, 30 июня, 30 сентября данного года) на основе ограничивающих дат уже предоставлено.

Итак, у меня есть столбец «Индекс» (IDNum), столбец «.id» (который считает IDNum) и два поля даты (Дата отчета и Дата расчета).

По сути, учитывая дату отчета и дату расчета, я хочу создать запись для каждой даты окончания квартала между этими двумя плюс данные отчета и даты расчета.

Например:

Дата отчета: 2001-12-29; Дата расчета: 2002-05-31

Это должно сгенерировать 4 записи:

  1. 2001-12-29
  2. 2001-12-31
  3. 2002-03-31
  4. 2002-05-31

Мне удалось воспроизвести строки правильное количество раз, и я могу получить две "простые" даты в там (первый и последний для каждой записи), но я борюсь с промежуточными датами (часть кода «Что здесь происходит»).

library(zoo)
    ClaimID_sam <- "1x1"
    ReptDat_sam <- strptime("2001-12-29", format = "%Y-%m-%d")
    SettDat_sam <- strptime("2002-05-31", format = "%Y-%m-%d")
    RecordCount <- as.integer((4*(as.yearqtr(SettDat_sam) - as.yearqtr(ReptDat_sam))) + 2)

    sam_DF <- data.frame(ClaimID_sam,ReptDat_sam,SettDat_sam,RecordCount)
    sam_DF <- as.data.frame(lapply(sam_DF,rep,RecordCount))
    sam_DF = getanID(sam_DF,"ClaimID_sam")

    sam_DF$ValDate <- ifelse(sam_DF$.id == 1, 
                                  as.Date(sam_DF$ReptDat_sam),
                                        "WHAT GOES HERE?????") 

    sam_DF$ValDate = ifelse(sam_DF$.id == sam_DF$RecordCount, 
                                  as.Date(sam_DF$SettDat_sam),
                                  sam_DF$ValDate)

РЕДАКТИРОВАТЬ @g Решение -grothendieck почти идеально, хотя и видит некоторые странности, не вполне достигающие конечных точек четверти?

   > do.call("rbind", by(ModData, ModData$ClaimID, add_dates))
       ClaimID Loss_Reported_Date settlementDate       ValuationDate
11X1.1    11X1         2001-12-29     2002-05-31 2001-12-29 00:00:00
11X1.2    11X1         2001-12-29     2002-05-31 2001-12-30 18:00:00
11X1.3    11X1         2001-12-29     2002-05-31 2002-03-30 18:00:00
11X1.4    11X1         2001-12-29     2002-05-31 2002-05-31 00:00:00
11X2.1    11X2         2002-04-06     2002-10-04 2002-04-06 00:00:00
11X2.2    11X2         2002-04-06     2002-10-04 2002-06-29 19:00:00
11X2.3    11X2         2002-04-06     2002-10-04 2002-09-29 19:00:00
11X2.4    11X2         2002-04-06     2002-10-04 2002-10-04 00:00:00

1 Ответ

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

Предположим, что наши входные данные - это фрейм данных со столбцами ID, st, en, как показано ниже. Значения st и en для разных идентификаторов могут отличаться.

Пример ниже имеет одинаковую дату начала и ту же дату окончания для каждого идентификатора, но код обрабатывает общий случай.

Использование функции make_dates для каждого входного идентификатора, т.е. для каждого строка, преобразуйте st и en в класс yearqtr, создайте последовательность между ними, преобразуйте в дату конца квартала (fra c = 1 означает конец квартала), включите st и en убедитесь, что ни один элемент не превышает en, и удалите дубликаты. Используйте group_by / group_modify, чтобы применить это к каждому идентификатору (то есть к каждой строке), или в конце мы показали, как использовать do.call/by в качестве альтернативы.

library(dplyr)
library(zoo)

# test input
inp <- data.frame(ID = 1:2, st = as.Date("2001-12-29"), en = as.Date("2002-05-31"))

# given dates st & en return a vector of them and intervening qtr ends
make_dates <- function(st, en) {
  st <- as.Date(st)
  en <- as.Date(en)
  yq1 <- as.yearqtr(st)
  yq2 <- as.yearqtr(en)
  dates <- as.Date(seq(yq1, yq2, 1/4), frac = 1)
  unique(pmin(c(st, dates, en), en))
}

inp %>%
  group_by(ID) %>%
  group_modify(~ cbind(., Date = make_dates(st, en))) %>%
  ungroup

, давая:

# A tibble: 8 x 4
     ID st         en         Date      
  <int> <date>     <date>     <date>    
1     1 2001-12-29 2002-05-31 2001-12-29
2     1 2001-12-29 2002-05-31 2001-12-31
3     1 2001-12-29 2002-05-31 2002-03-31
4     1 2001-12-29 2002-05-31 2002-05-31
5     2 2001-12-29 2002-05-31 2001-12-29
6     2 2001-12-29 2002-05-31 2001-12-31
7     2 2001-12-29 2002-05-31 2002-03-31
8     2 2001-12-29 2002-05-31 2002-05-31

Альтернативно конвейер dplyr можно выполнить без dplyr, например:

add_dates <- function(x) with(x, data.frame(ID, st, en, Date = make_dates(st, en)))
do.call("rbind", by(inp, inp$ID, add_dates))

Обновление

Обновление несколько раз.

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