将数据框转换为r

时间:2018-10-08 18:50:55

标签: r panel reshape

我有以下贷款数据集。对于我要求的amount的每笔贷款,是贷款发出的日期issue_date,上次付款网络收到的日期last_payment_datemonths_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语言中的专业程序员来说应该并不困难。

请查看平衡的面板数据集结构的外观,以更好地了解即时消息的要求。所有贷款都已到期。

有什么建议吗?

谢谢

2 个答案:

答案 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_passedterm - months_passedid次。 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上将生成的idNA结合在一起