преобразовать фрейм данных в набор данных панели в r - PullRequest
0 голосов
/ 08 октября 2018

У меня есть следующий набор данных кредита.Для каждого ссуды, которую я запрашивал amount, дату выдачи ссуды issue_date, дату последнего полученного платежа last_payment_date, months_passed, которая представляет собой разницу в месяцах между issue_date и last_payment_date, ссудойterm является ли 36 для всех ссуд и status ссуды.

Статус займа

(a) «Снято», если paymnet опаздывает более чем на 120 дней, то есть на 4+ месяца

(b) «Полностью оплачено», если выплаченовесь кредит обратно

(c) «Не соответствует кредитной политике. Статус: списан», аналогично (a)

(d) «Не соответствует кредитной политике. Статус:Полностью оплачен "как (b)

(e)" По умолчанию "такой же, как (а)

df <- data.frame(id=c("John","Ben","Bill", "Eminem"),
                  amount=c("300", "500", "1000", "1200"),
                  issue_date=c("2010-01-01","2011-01-01","2012-01-01", "2015-02-01"),
                  last_pymnt_date=c("2013-02-01","2012-05-01","2014-01-01", "2018-02-01"),
                  months_passed=c(37,16,24,36),
                  term = c("36", "36", "36", "36"),
                  status=c("Fully paid",
                           "Charged off",
                           "Does not meet the credit policy. Status:Charged Off",
                           "Does not meet the credit policy. Status:Fully Paid"),
             stringsAsFactors = F)

Я создаю интервал времени, который будет первым столбцом панели, следующим образом

time_interval <- as.data.frame(rep(seq(from = as.Date("2007-08-01"),
                                       to = as.Date("2018-02-01"),
                                       by = "month"),
                                   4))
colnames(time_interval) <- c("time")

Я хочу преобразовать его в набор данных PANEL , заполнив следующие данные:

1 - Каждый заем будет иметь даты с августа 2007 г. - февраль 2018 г., нопоявится только тогда, когда он жив.То есть, если кредит, выданный в августе 2008 года, появится с августа 2008 года по август 2011 года, то есть 36 строк.До и после этой даты мы ничего не знаем о ссуде, поэтому пропущенным значениям следует присваивать переменные (кроме переменной месяца, которая должна быть 1-м столбцом).

2 - добавить столбец months, который будет1,2,3, ..., 35,36

3- Рядом с ним я хочу добавить еще одну фиктивную переменную paid, поскольку я хочу определить, сделал ли заемщик платежную сеть месяца илинет, основываясь на status.Если кредит имеет status «Полностью оплачен» или «Не соответствует кредитной политике. Статус: Полностью оплачен», то в столбце paid будут все единицы (1) в течение 36 месяцев, если status - «Вычтено»"или" Не соответствует кредитной политике. Статус: списан "у нас будут единицы до последней даты paymnet и все нули после этого.Для Бена у нас будет 16 единиц и 20 нулей.

См. Выше объяснение статусов, которые помогут структурировать переменную paid ( ОЧЕНЬ ВАЖНО )

Программирование для такого любителя, как я, выглядит сложным, но для опытного программиста в R. это не должно быть трудным.

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

Есть предложения?

Спасибо

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

Вот вариант base R.

reps <- c(rbind(df$months_passed,
                as.numeric(as.character(df$term)) - df$months_passed))

df2 <- data.frame(id = rep(unique(df$id), df$term), 
                  paid = rep(rep(c(1, 0), length(unique(df$id))), times = reps),
                  stringsAsFactors = FALSE)

merge(df, df2, sort = FALSE)
#      id amount issue_date last_pymnt_date months_passed term paid
#1   John    300 2010-01-01      2011-01-01            12   30    1
#2   John    300 2010-01-01      2011-01-01            12   30    1
#3   John    300 2010-01-01      2011-01-01            12   30    1
#4   John    300 2010-01-01      2011-01-01            12   30    1
#5   John    300 2010-01-01      2011-01-01            12   30    1
#6   John    300 2010-01-01      2011-01-01            12   30    1
#7   John    300 2010-01-01      2011-01-01            12   30    1
#8   John    300 2010-01-01      2011-01-01            12   30    1
#9   John    300 2010-01-01      2011-01-01            12   30    1
#10  John    300 2010-01-01      2011-01-01            12   30    1
#11  John    300 2010-01-01      2011-01-01            12   30    1
#12  John    300 2010-01-01      2011-01-01            12   30    1
#13  John    300 2010-01-01      2011-01-01            12   30    0
# ...

Идея состоит в том, чтобы создать вектор, повторяющийся c(1, 0) раз months_passed и term - months_passed для каждого id.df2 содержит ту информацию, которую мы можем объединить с df на id.


Другая идея с использованием data.table

library(data.table)
setDT(df)
df[df[, .(paid = `length<-`(rep(1, months_passed), term)), by = id], on = "id"
   ][, paid := replace(paid, is.na(paid), 0)][]

Здесь мы создаем столбец paidво-первых, как вектор, содержащий 1 (повторяется months_passed раз) и NA с использованием "length<-".Этот вектор будет иметь длину term для каждого id.

Аналогично решению base R мы объединяем получившиеся data.table с df на id после того, как мы заменили NA нулями, чтобы получить желаемый результат.

0 голосов
/ 08 октября 2018

образец данных

df <- data.frame(id=c("John","Ben","Bill"),
                 amount=c("300", "500", "1000"),
                 issue_date=c("2010-01-01","2011-01-01","2012-01-01"),
                 last_pymnt_date=c("2011-01-01","2011-07-01","2014-01-01"),
                 months_passed=c(12,6,24),
                 term = c("30", "30", "60"),
                 stringsAsFactors = FALSE)   # <<-----  !!!!

решение таблицы данных

library( data.table )
library( lubridate )
dt <- as.data.table( df ) #or setDT( df ) when working with (very) large datasets, to save memory
#set data as posix
dt[, `:=`( issue_date = as.Date( issue_date), last_pymnt_date = as.Date( last_pymnt_date ) )]

result <- dt[ , list(id = id, 
                     amount = amount, 
                     month = seq( from = issue_date, to = issue_date %m+% months( as.numeric( term ) - 1), by = "month" ),
                     paid = rep( rep( c(1,0), times = .N ), times = as.vector(rbind( months_passed, as.numeric( term ) - months_passed ) ) )
                     ), 
    by = 1:nrow(dt)][, nrow := NULL]

#        id amount      month paid
#   1: John    300 2010-01-01    1
#   2: John    300 2010-02-01    1
#   3: John    300 2010-03-01    1
#   4: John    300 2010-04-01    1
#   5: John    300 2010-05-01    1
# ---                            
# 116: Bill   1000 2016-08-01    0
# 117: Bill   1000 2016-09-01    0
# 118: Bill   1000 2016-10-01    0
# 119: Bill   1000 2016-11-01    0
# 120: Bill   1000 2016-12-01    0
...