我有以下贷款数据集。对于我要求的amount
的每笔贷款,是贷款发出的日期issue_date
,上次付款网络收到的日期last_payment_date
,months_passed
,这是{{ 1}}和issue_date
,则贷款last_payment_date
是否为所有贷款的36和贷款的term
。
贷款状态为
(a)如果Paymnet延迟超过120天(即4个月以上),则“收费”
(b)如果已偿还了所有贷款,则为“全额偿还”
(c)“不符合信用政策。状态:已收费”与(a)相同
(d)“不符合信用政策。状态:已全额付款”,与(b)相同
(e)“默认”与(a)相同
status
我创建时间间隔,该时间间隔将成为面板的第一列,如下所示
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)
我想通过填写以下内容将其转换为 PANEL 数据集:
1-每笔贷款的日期为2007年8月至2018年2月,但仅在还活期时才会显示。也就是说,如果2008年8月发行的贷款从2008年8月至2011年8月出现,即36行。在此日期之前和之后,我们对贷款一无所知,因此应将缺失值分配给变量(月份变量除外,该变量应在第一列)。
2-添加一列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")
,该列将为1,2,3,...,35,36
3-在它旁边,我想添加另一个虚拟变量months
,因为我想基于paid
来捕获借款人是否已完成当月的支付网。如果status
的贷款是“已付清”或“不符合信贷政策。状态:已付”,则status
在{{1 }}是“已收费”或“不符合信用政策。状态:已收费”,我们将在最后一个paymnet日期之前将其清零,之后将全部清零。对于本,我们将有16个1和20个零。
请参阅上面的说明,以了解有助于构造变量paid
(非常重要)
对于像我这样的业余爱好者来说,编写此程序看起来很复杂,但是对于R语言中的专业程序员来说应该并不困难。
请查看平衡的面板数据集结构的外观,以更好地了解即时消息的要求。所有贷款都已到期。
有什么建议吗?
谢谢
答案 0 :(得分:0)
样本数据
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
答案 1 :(得分:0)
这是一个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
结合在一起