【问题标题】:convert data frame to a panel dataset in r将数据框转换为 r 中的面板数据集
【发布时间】:2018-10-08 18:50:55
【问题描述】:

我有以下贷款数据集。对于每笔贷款,我都要求amount,贷款发放日期issue_date,最后一次paymnet收到日期last_payment_datemonths_passed这是issue_datelast_payment_date之间的月差,贷款term 是否是所有贷款的 36 和贷款的 status

贷款状态是

(a)如果 paymnet 延迟超过 120 天,即 4 个月以上,则“扣款”

(b)“全额支付”如果已偿还所有贷款

(c)“不符合信用政策。状态:Charged Off”同(a)

(d)“不符合信用政策。状态:全额支付”同(b)

(e)“默认”同(a)

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 年 8 月至 2018 年 2 月,但仅在有效时才会出现。也就是说,如果 2008 年 8 月发放的贷款将从 2008 年 8 月到 2011 年 8 月出现,即 36 行。在此日期之前和之后,我们对贷款一无所知,因此应将缺失值分配给变量(应为第一列的月份变量除外)。

2-添加一列months,它将是 1,2,3,...,35,36

3- 在它旁边我想添加另一个虚拟变量paid,因为我想根据status 捕捉借款人是否已完成当月的付款。如果贷款有status 是“全额支付”或“不符合信用政策。状态:全额支付”而不是paid 列将是全1(1) 36 个月,如果status 是“已注销” ”或“不符合信用政策。状态:已注销”我们将在最后一个付款日期之前拥有一个,之后全为零。对于 Ben,我们将有 16 个 1 和 20 个 0。

有关有助于如何构造变量 paid(非常重要) 的状态的说明,请参阅上面的说明

这对于像我这样的业余爱好者来说看起来很复杂,但对于 R 中的专家级程序员来说应该不难。

请查看平衡面板数据集结构的外观,以便更好地理解我的要求。所有贷款均已到期。

有什么建议吗?

谢谢

【问题讨论】:

    标签: r panel reshape


    【解决方案1】:

    样本数据

    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
    

    【讨论】:

    • 谢谢。通常数据集很大并且有很多其他变量。我应该如何保留其他变量?
    • @Erick,您可以创建一个 ID,然后执行左连接,或者在创建新 data.table 时将它们包含在list 中,就像在id = id, 的答案中所做的那样和amount = amount,,只需将yourvan = yourvar, 添加到列表中...
    • Wimpel 你能再看看qs吗?我已经更新了。它略有不同。谢谢
    【解决方案2】:

    这是一个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
    # ...
    

    这个想法是为每个id 创建一个重复c(1, 0)months_passedterm - months_passed 的向量。 df2 包含我们可以在 id 上与 df 合并的信息。


    另一个使用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&lt;-" 的向量。对于每个id,此向量的长度为term

    base R 解决方案类似,我们将id 上的dfdf 相结合,之后我们将NA 替换为零以获得所需的输出。

    【讨论】:

    • 谢谢。通常数据集很大并且有很多其他变量。我应该如何保留其他变量?
    • 我认为这两个答案都很笼统。将这些方法应用于数据时出了什么问题?在这两个答案中,您最后要做的就是将paid 列加入您现有的数据。
    • 我意识到months_passed 的某些值高于term 的值,这使代表负数
    • 如果paid 列的长度不应超过term,那么data.table 解决方案应该可以正常工作。如果没有,请考虑举一个更现实的例子。
    • 返回此错误。 " as.vector(x, "list") 中的错误:无法将类型 'closure' 强制转换为类型为 'list' 的向量“
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-22
    • 2021-03-24
    • 2021-05-16
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多