Расчет скользящей просрочки для фрейма данных

Я новичок в R и пытаюсь найти работу, чтобы рассчитать просрочку платежа за 3 месяца на постоянной основе.

Мой кадр данных состоит из (CID, Acquistion_date и delinquient)

я пытаюсь создать новый dataframe с добавлением 4-го столбца (Roll_deliquency), т.е. количество правонарушителей за последние 3 месяца). Как только у нас появится новый идентификатор клиента, мы снова начнем с первой транзакции этого клиента. Roll_Deliquiency — это общее количество просроченных платежей только за последние 3 месяца только.

ожидаемый результат, как показано ниже

CID AQ_DATE   Delinquient Roll_Deliquiency
103   2007/03/18    1       0
103   2007/04/03    0       1
103   2007/04/17    0       1
103   2007/05/03    0       1
103   2007/05/17    1       1
103   2007/06/02    1       2
103   2007/06/16    1       3
103   2007/07/02    1       3
103   2008/01/03    1       0
103   2008/01/17    1       1
103   2008/02/02    0       2
103   2008/02/16    1       2
105   2007/01/01    1       0
105   2007/01/11    1       1 
105   2007/02/10    1       2
105   2007/02/14    0       3
105   2007/02/17    1       3    
105   2007/02/17    1       4
105   2007/02/17    1       5
105   2007/04/02    0       5  
105   2007/04/10    1       5  

Может ли кто-нибудь помочь мне с кодом R? Я пытался использовать скользящее применение, но не смог настроить его в соответствии с потребностями.


person user2109967    schedule 26.02.2013    source источник
comment
Я бы сказал, что вы хотите использовать cumsum, но ваш пример Roll_Delinquincy не соответствует cumsum. Объясните понятнее, что такое столбец. потому что это явно не совокупное количество правонарушителей к тому времени.   -  person Paul Hiemstra    schedule 26.02.2013
comment
НЕТ это не кумсум. Я изменил задачу для большей ясности. пожалуйста, дайте мне знать, если вам все еще трудно понять логику.   -  person user2109967    schedule 27.02.2013
comment
Вы уверены, что внизу правой колонки должно быть три пятерки?   -  person Mark Miller    schedule 28.02.2013


Ответы (1)


Это может быть не то, что вы хотите, но это лучшее, что я могу сделать с моим нынешним пониманием проблемы. Для каждого человека и каждой даты в файле данных я вернулся на 90 дней назад и суммировал количество просрочек. Мои результаты хранятся в векторе my.count. Мои результаты не соответствуют Roll_Deliquiency. Однако, возможно, это поможет вам начать. Если вы предоставите дополнительную информацию о том, как рассчитывается Roll_Deliquiency, возможно, я смогу изменить приведенный ниже код. Я мог бы также немного почистить код в ближайшее время. В настоящее время он включает в себя некоторые переменные, которые я не использовал для получения ответа.

df.1 <- read.table(text='
CID AQ_DATE   Delinquient Roll_Deliquiency
103   2007/03/18    1       0
103   2007/04/03    0       1
103   2007/04/17    0       1
103   2007/05/03    0       1
103   2007/05/17    1       1
103   2007/06/02    1       2
103   2007/06/16    1       3
103   2007/07/02    1       3
103   2008/01/03    1       0
103   2008/01/17    1       1
103   2008/02/02    0       2
103   2008/02/16    1       2
105   2007/01/01    1       0
105   2007/01/11    1       1
105   2007/02/10    1       2
105   2007/02/14    0       3
105   2007/02/17    1       3
105   2007/02/17    1       4
105   2007/02/17    1       5
105   2007/04/02    0       5
105   2007/04/10    1       5', header=T, colClasses=c('character', 'character', 'integer', 'integer'))

df.1$AQ_DATE2 <- as.Date(df.1$AQ_DATE, "%Y/%m/%d")

df.1$running.count = sequence(rle(df.1$CID)$lengths)
df.1

max.value <- data.frame(id.max = with(df.1, tapply(running.count, CID, function(x) x[length(x)])))
max.value

max.value$CID <- row.names(max.value)
max.value

all.data  <- merge(max.value, df.1, by=c('CID'), all = TRUE)
all.data

my.count <- rep(0, nrow(all.data))

m <- 1

for(i in length(unique(all.data$CID)):1) {

  all.data.i <- subset(all.data, all.data$CID == max.value$CID[i])

    print(all.data.i)

     for(j in nrow(all.data.i):1) {

        for(k in j:1) {

           if(((j-k) >  1) &
             (as.numeric(all.data.i$AQ_DATE2[j] - all.data.i$AQ_DATE2[k+1]) <= 90)  &    
             (as.numeric(all.data.i$AQ_DATE2[j] - all.data.i$AQ_DATE2[k  ]) >  90)) my.count[m] = sum(all.data.i$Delinquient[(k+1):j]) 

           if(((j-k) == 1) &
              as.numeric(all.data.i$AQ_DATE2[j] - all.data.i$AQ_DATE2[k])   >  90)  my.count[m] = all.data.i$Delinquient[j]

           if((k == 1) &
              as.numeric(all.data.i$AQ_DATE2[j] - all.data.i$AQ_DATE2[1])   <= 90)  my.count[m] = sum(all.data.i$Delinquient[1:j])

         } 

     m = m + 1

     }     

}

my.count

 [1] 6 5 6 5 4 3 3 2 1 3 2 2 1 4 4 3 2 1 1 1 1
person Mark Miller    schedule 28.02.2013
comment
Отметить Я предполагаю, что ваш ответ не соответствует только в тех случаях, когда существует более 1 транзакции на одну и ту же дату, и в случаях, когда счетчик установлен на 0. Я согласен с этим и пытаюсь догнать ваш код. Более того, я также вижу, что вы отображаете записи в порядке убывания. - person user2109967; 28.02.2013
comment
Логика Roll_deliquiency: для row1 Roll_Deliquiency равен 0, так как более ранних записей нет. то же самое для строки 9 (так как это начало нового периода) и строки 13 в качестве нового клиента. для row6 Roll_Deliquiency равно 2, потому что, если вы пройдете вверх, вы увидите, что все aq_date находится в пределах 3 месяцев. мы не учитываем текущую просрочку строки. аналогично row7 равен 3, потому что AQ_DATE для row7 равен 2007/06/16, и если вы снова перемещаетесь вверх, то есть от строки 6 к строке 1, все AQ_DATE для каждой строки находится в пределах 90 дней от row7. - person user2109967; 28.02.2013
comment
Вы можете изменить порядок элементов в my.count, используя: rev(my.count). - person Mark Miller; 28.02.2013