Назначить ежемесячную запись даты для каждого идентификатора из начальных дат в DF

#r #dataframe #date #sequence

#r #фрейм данных #Дата #последовательность

Вопрос:

У меня есть фрейм данных «DF», подобный этому:

   Id    Ctrl_num   Ctrl_date
00167      1       1988-10-15
00167      2           NA
00167      3           NA
00168      1       1990-02-15
00168      2           NA
00168      3           NA
00207      1       1988-11-15
00207      2           NA
00207      3           NA
  

Важно: Crtl_date столбец отображается как.Формат даты

Что мне нужно сделать, так это сгенерировать недостающие Crtl_date значения. Я получил первую контрольную дату для каждого Id , и я знаю, что следующие элементы управления выполнялись с ежемесячной частотой.

DF должен выглядеть следующим образом:

  Id    Ctrl_num   Ctrl_date
00167    1        1988-10-15
00167    2        1998-11-14
00167    3        1998-12-14
00168    1        1990-02-15
00168    2        1990-03-17
00168    3        1990-04-16
00207    1        1988-11-15
00207    2        1988-12-15
00207    3        1989-01-14
  

Моя лучшая попытка

 DF$Ctrl_date2 <- seq(as.Date('1988-10-15'), by='30 day', length=3)

  

Моя проблема здесь в том, что я не знаю, как заставить ежемесячную последовательность элементов управления начинаться с первого существующего элемента управления для каждого идентификатора.

Ответ №1:

Выполнение этого кода должно дать вам вектор, состоящий из того, что вы хотите:

 #Defining data
Id = c(00167,00167,00167,00168,00168,00168,00207,00207,00207)
Ctrl_num = c(1,2,3,1,2,3,1,2,3)
Ctrl_date = c('1988-10-15',NA,NA,'1990-02-15',NA,NA, '1988-11-15',NA,NA)
df = data.frame(Id, Ctrl_num, Ctrl_date)

#Finds index of known dates
ID = which(!is.na(df$Ctrl_date))
#Finds needed length of sequence
d = diff(c(ID, length(df$Ctrl_date)   1))

#Creates new date-vector
ctrl_date2 = as.Date(rep(NA,length(df$Ctrl_date)))
for(i in 1:length(ID)){
  ctrl_date2[ID[i]:(ID[i] d[i]-1)] = seq(as.Date(df$Ctrl_date[ID[i]]), 
                                         by='30 day', length.out=d[i])
}
ctrl_date2