Создать исторические данные - PullRequest
0 голосов
/ 13 июля 2020

Мне нужно подготовить исторические данные с даты начала до даты окончания (30-04-2020). Дата начала отличается в зависимости от пользователя. Дата окончания остается одинаковой для всех пользователей (30-04-2020).

data <- read.table(text = "User  StartDate
1     24-04-2019
2     31-07-2019
3     2015-10-27", header = TRUE)

Желаемый результат - каждая дата должна иметь последний день месяца от начальной до конечной даты для каждого пользователя

User ID DesiredDate
1   4/30/2019
1   5/31/2019
1   6/30/2019
1   7/31/2019
1   8/31/2019
1   9/30/2019
1   10/31/2019
1   11/30/2019
1   12/31/2019
1   1/31/2020
1   2/29/2020
1   3/31/2020
1   4/30/2020

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Вот возможное решение с использованием lubridate и tidyverse:

library(tidyverse)
library(lubridate)

data %>% 
  mutate(date1 = dmy(StartDate),
         date2 = ymd(StartDate),
         StartDate = coalesce(date1,date2),
         StartDate = -1 + ceiling_date(StartDate, unit = 'month'),
         EndDate = ymd(c("2020-04-30"))) %>% 
  select(User, StartDate, EndDate) %>% 
  group_by(User) %>% 
  transmute(User, DesiredDate = map2(StartDate, EndDate, seq, by = "1 month")) %>% 
  unnest %>% 
  mutate(DesiredDate = -1 + ceiling_date(DesiredDate, unit = 'month'))

Что дает нам:

  User DesiredDate
   <int> <date>     
 1     1 2019-04-30 
 2     1 2019-05-31 
 3     1 2019-06-30 
 4     1 2019-07-31 
 5     1 2019-08-31 
 6     1 2019-09-30 
 7     1 2019-10-31 
 8     1 2019-11-30 
 9     1 2019-12-31 
10     1 2020-01-31 
11     1 2020-03-31 
12     1 2020-03-31 
13     1 2020-04-30 
14     2 2019-07-31 
15     2 2019-08-31 
16     2 2019-10-31 
17     2 2019-10-31 
18     2 2019-12-31 
19     2 2019-12-31 
20     2 2020-01-31 
0 голосов
/ 13 июля 2020

Вы можете попробовать следующее:

#Data
data <- structure(list(User = 1:3, StartDate = c("24-04-2019", "31-07-2019", 
"27-10-2015")), row.names = c(NA, -3L), class = "data.frame")
structure(list(User = 1:3, StartDate = c("24-04-2019", "31-07-2019", 
"27-10-2015")), row.names = c(NA, -3L), class = "data.frame")

#Create list by id
List <- split(data,data$User)
#Endpoint
endpoint <- as.Date('30-04-2020','%d-%m-%Y')
#Build function for sequences
builddata <- function(x)
{
  val1 <- x$User
  valstart <- as.Date(x$StartDate,'%d-%m-%Y')
  seqdate <- seq(valstart,endpoint,by='1 day') 
  datadates <- data.frame(User=rep(val1,length(seqdate)),Date=seqdate,stringsAsFactors = F)
  return(datadates)
}
#Apply function
List <- lapply(List,builddata)
#Bind all
df <- do.call(rbind,List)
rownames(df)<-NULL

В итоге вы получите фрейм данных из 2296 строк и 2 столбцов. Я включаю несколько строк:

  User       Date
1    1 2019-04-24
2    1 2019-04-25
3    1 2019-04-26
4    1 2019-04-27
5    1 2019-04-28
6    1 2019-04-29
...