【问题标题】:Emi calculation for the grace month in RR中宽限月的EMI计算
【发布时间】:2020-07-15 06:22:51
【问题描述】:

根据我之前的问题,我试图简化计算。我将以下变量保存到我的数据框中。

dataframe1:这是正常情况。

uid     emi_date    amt interest    tenure  emi      Rep_seq    status  balance
KII-453 01/01/2020  100 2%          12      10.33333    1          1    113.67
KII-453 01/02/2020  100 2%          12      10.33333    2          1    103.3367
KII-453 01/03/2020  100 2%          12      10.33333    3          1    93.00333
KII-453 01/04/2020  100 2%          12      10.33333    4          0    82.67
KII-453 01/05/2020  100 2%          12      10.33333    5          0    72.33667
KII-453 01/06/2020  100 2%          12      10.33333    6          0    62.00333
KII-453 01/07/2020  100 2%          12      10.33333    7          0    51.67
KII-453 01/08/2020  100 2%          12      10.33333    8          0    41.33667
KII-453 01/09/2020  100 2%          12      10.33333    9          0    31.00333
KII-453 01/10/2020  100 2%          12      10.33333    10         0    20.67
KII-453 01/11/2020  100 2%          12      10.33333    11         0    10.33667
KII-453 01/12/2020  100 2%          12      10.33333    12         0    0.003333

从dataframe1,我试图提供下一个x 月的宽限期(其中x = 2 个月,但也可以是几天,以便我想保持可配置)从上一个状态= 1(对于上面的数据框是emi_date = 01/03/2020

余额计算 (row1) = 124 - 10.333 =113.67, row2 及以后 = 余额 row1(113.67)-emi(10.333)

需要输出 数据框2:

uid     emi_date    amt interest    tenure  emi       rep_seq   status  balance
KII-453 01/01/2020  100   2%          12    10.33333    1         1     113.67
KII-453 01/02/2020  100   2%          12    10.33333    2         2     103.3367
KII-453 01/03/2020  100   2%          12    10.33333    3         3     93.00333
KII-453 01/04/2020  100   2%          12    0           4         0     95.00333
KII-453 01/05/2020  100   2%          12    0           5         0     97.04333
KII-453 01/06/2020  100   2%          12    10.33333    6         0     86.71
KII-453 01/07/2020  100   2%          12    10.33333    7         0     76.37667
KII-453 01/08/2020  100   2%          12    10.33333    8         0     66.04333
KII-453 01/09/2020  100   2%          12    10.33333    9         0     55.71
KII-453 01/10/2020  100   2%          12    10.33333    10        0     45.37667
KII-453 01/11/2020  100   2%          12    10.33333    11        0     35.04333
KII-453 01/12/2020  100   2%          12    10.33333    12        0     24.71
KII-453 01/01/2021  100   2%          12    10.33333    13        0     14.37667
KII-453 01/02/2021  100   2%          12    10.33333    14        0     4.043333
KII-453 01/03/2021  100   2%          12    4.043333    15        0     0

余额计算 (row1) = 124 - 10.333 =113.67, row2 及以后直到状态 (1) = balance row1(113.67)-emi(10.333)

要添加宽限期,我们将接下来的两个月 emi 设为 0。这两个月的余额计算将是 01/04/2020 = amt(100)*interest(2%) + 之前的余额 (93.00333) 和对于01/05/2020 = (amt(100)*interest(2%))+(amt(100)*interest(2%))*2%+ 之前的余额 (95.00333)

剩余余额计算将保持原样(例如,以前的余额 - emi)直到余额

P.S - 使用的兴趣方法是平坦的,为了减少我正在尝试构建的逻辑,如果 SO 也可以帮助我,这将是有帮助的。

出于示例目的,我为一个 uid 创建了数据框,实际上我在数据框中有 ~10000 个唯一 uid。

输入输出:

    structure(list(uid = c("KII-62", "KII-62", "KII-62", 
"KII-62", "KII-62", "KII-62", "KII-62", 
"KII-62", "KII-62", "KII-62", "KII-62", 
"KII-62", "KII-62", "KII-62", "KII-62", 
"KII-62", "KII-62", "KII-62", "KII-62", 
"KII-62", "KII-62", "KII-62", "KII-62", 
"KII-62", "KII-63", "KII-63", "KII-63", 
"KII-63", "KII-63", "KII-63", "KII-63", 
"KII-63", "KII-63", "KII-63", "KII-63", 
"KII-63"), emi_date = c("05/12/2019", "05/01/2020", "05/02/2020", 
"05/03/2020", "05/04/2020", "05/05/2020", "05/06/2020", "05/07/2020", 
"05/08/2020", "05/09/2020", "05/10/2020", "05/11/2020", "05/12/2020", 
"05/01/2021", "05/02/2021", "05/03/2021", "05/04/2021", "05/05/2021", 
"05/06/2021", "05/07/2021", "05/08/2021", "05/09/2021", "05/10/2021", 
"05/11/2021", "05/12/2019", "05/01/2020", "05/02/2020", "05/03/2020", 
"05/04/2020", "05/05/2020", "05/06/2020", "05/07/2020", "05/08/2020", 
"05/09/2020", "05/10/2020", "05/11/2020"), amt = c(470000, 470000, 
470000, 470000, 470000, 470000, 470000, 470000, 470000, 470000, 
470000, 470000, 470000, 470000, 470000, 470000, 470000, 470000, 
470000, 470000, 470000, 470000, 470000, 470000, 220000, 220000, 
220000, 220000, 220000, 220000, 220000, 220000, 220000, 220000, 
220000, 220000), interest = c(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2), tenure = c(24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 12, 12, 
12, 12, 12, 12, 12, 12, 12, 12, 12, 12), emi = c(28983.33, 28983.33, 
28983.33, 28983.33, 28983.33, 28983.33, 28983.33, 28983.33, 28983.33, 
28983.33, 28983.33, 28983.33, 28983.33, 28983.33, 28983.33, 28983.33, 
28983.33, 28983.33, 28983.33, 28983.33, 28983.33, 28983.33, 28983.33, 
28983.33, 22733.33, 22733.33, 22733.33, 22733.33, 22733.33, 22733.33, 
22733.33, 22733.33, 22733.33, 22733.33, 22733.33, 22733.33), 
    Rep_seq = c("1", "2", "3", "4", "5", "6", "7", "8", "9", 
    "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", 
    "20", "21", "22", "23", "24", "1", "2", "3", "4", "5", "6", 
    "7", "8", "9", "10", "11", "12"), status = c(1L, 1L, 1L, 
    1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L), balance = c(450416.666666667, 430833.333333333, 
    411250, 391666.666666667, 372083.333333333, 352500, 332916.666666667, 
    313333.333333333, 293750, 274166.666666667, 254583.333333333, 
    235000, 215416.666666667, 195833.333333333, 176250, 156666.666666667, 
    137083.333333333, 117500, 97916.6666666667, 78333.3333333333, 
    58750, 39166.6666666667, 19583.3333333333, 8e-28, 201666.666666667, 
    183333.333333333, 165000, 146666.666666667, 128333.333333333, 
    110000, 91666.6666666667, 73333.3333333333, 55000, 36666.6666666667, 
    18333.3333333333, 4e-28)), .Names = c("uid", "emi_date", 
"amt", "interest", "tenure", "emi", "Rep_seq", "status", "balance"
), class = "data.frame", row.names = c(NA, 36L))

uid = KII-62 的第 1 行余额将是 (amt * interest *tenure)+amt,uid = KII-63 的第 1 行余额将重复此操作

第 1 行余额 (KII-62): (4,70,000*0.02)-28983.33(emi) = 450416.666666667

【问题讨论】:

    标签: r dataframe ggplot2 dplyr tidyverse


    【解决方案1】:

    这是一个完全依赖tidyverse的解决方案。

    library(tidyverse)
    startingbalance <- 124
    period <- "1 month"
    dataframe1 %>% 
      mutate(index = seq(1,nrow(.))) %>%
      mutate(emi_date = dmy(emi_date)) %>%
      mutate(emi = case_when(status - lag(status) < 0 ~ 0, status - lag(status,2L) < 0 ~ 0, TRUE ~ emi)) %>%
      mutate(balance = case_when(index == 1 ~ startingbalance - emi,
                                    index > 1 & emi > 0 & status == 1 ~ lag(balance) - emi,
                                    index > 1 & emi == 0 & lag(status) == 1 & lag(status,2L) == 1 ~ lag(balance) + (amt * (as.integer(gsub("%","",interest))) / 100),
                                    index > 1 & emi == 0 & lag(status) == 0 & lag(status,2L) == 1 ~ lag(balance,2L) + 2 * (amt * (as.integer(gsub("%","",interest))) / 100),
                                    TRUE ~ NaN)) %>%
      select(-index) %>%
      do(add_row(., uid = .$uid[nrow(.)],emi_date = .$emi_date[nrow(.)] + period(period), amt = .$amt[nrow(.)],interest = .$interest[nrow(.)],tenure = .$tenure[nrow(.)],emi = .$emi[nrow(.)],status = .$status[nrow(.)],Rep_seq = .$Rep_seq[nrow(.)] + 1,balance = NaN)) %>% 
      do(add_row(., uid = .$uid[nrow(.)],emi_date = .$emi_date[nrow(.)] + period(period), amt = .$amt[nrow(.)],interest = .$interest[nrow(.)],tenure = .$tenure[nrow(.)],emi = .$emi[nrow(.)],status = .$status[nrow(.)],Rep_seq = .$Rep_seq[nrow(.)] + 1,balance = NaN)) %>%
      do(add_row(., uid = .$uid[nrow(.)],emi_date = .$emi_date[nrow(.)] + period(period), amt = .$amt[nrow(.)],interest = .$interest[nrow(.)],tenure = .$tenure[nrow(.)],emi = .$emi[nrow(.)],status = .$status[nrow(.)],Rep_seq = .$Rep_seq[nrow(.)] + 1,balance = NaN)) %>%
      mutate(balance =  {ind <- which(is.nan(balance)); for(i in ind){balance[i] <- balance[i-1] - emi[i]}; balance}) %>%
      mutate(emi = case_when(balance < 0 ~ lag(balance), TRUE ~ emi),
             balance = case_when(balance < 0 ~ 0, TRUE ~ balance))
    #       uid   emi_date amt interest tenure      emi Rep_seq status   balance
    #1  KII-453 2020-01-01 100       2%     12 10.33333       1      1 113.66667
    #2  KII-453 2020-02-01 100       2%     12 10.33333       2      1 103.33667
    #3  KII-453 2020-03-01 100       2%     12 10.33333       3      1  93.00337
    #4  KII-453 2020-04-01 100       2%     12  0.00000       4      0  95.00333
    #5  KII-453 2020-05-01 100       2%     12  0.00000       5      0  97.00333
    #6  KII-453 2020-06-01 100       2%     12 10.33333       6      0  86.67000
    #7  KII-453 2020-07-01 100       2%     12 10.33333       7      0  76.33667
    #8  KII-453 2020-08-01 100       2%     12 10.33333       8      0  66.00334
    #9  KII-453 2020-09-01 100       2%     12 10.33333       9      0  55.67001
    #10 KII-453 2020-10-01 100       2%     12 10.33333      10      0  45.33668
    #11 KII-453 2020-11-01 100       2%     12 10.33333      11      0  35.00335
    #12 KII-453 2020-12-01 100       2%     12 10.33333      12      0  24.67002
    #13 KII-453 2021-01-01 100       2%     12 10.33333      13      0  14.33669
    #14 KII-453 2021-02-01 100       2%     12 10.33333      14      0   4.00336
    #15 KII-453 2021-03-01 100       2%     12  4.00336      15      0   0.00000
    

    我不得不分解并使用自定义函数重新计算余额,并且添加新行非常混乱。任何改进建议将不胜感激。

    数据

    dataframe1 <- structure(list(uid = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L), .Label = "KII-453", class = "factor"), emi_date = structure(1:12, .Label = c("01/01/2020", 
    "01/02/2020", "01/03/2020", "01/04/2020", "01/05/2020", "01/06/2020", 
    "01/07/2020", "01/08/2020", "01/09/2020", "01/10/2020", "01/11/2020", 
    "01/12/2020"), class = "factor"), amt = c(100L, 100L, 100L, 100L, 
    100L, 100L, 100L, 100L, 100L, 100L, 100L, 100L), interest = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "2%", class = "factor"), 
        tenure = c(12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 
        12L, 12L), emi = c(10.33333, 10.33333, 10.33333, 10.33333, 
        10.33333, 10.33333, 10.33333, 10.33333, 10.33333, 10.33333, 
        10.33333, 10.33333), Rep_seq = 1:12, status = c(1L, 1L, 1L, 
        0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), balance = c(113.67, 
        103.3367, 93.00333, 82.67, 72.33667, 62.00333, 51.67, 41.33667, 
        31.00333, 20.67, 10.33667, 0.003333)), class = "data.frame", row.names = c(NA, 
    -12L))
    

    【讨论】:

    • @lan Campbell:谢谢,它工作得很好,但如果我们可以使用一些财务库,比如Fincaltvm 等,那就太好了。请帮助减少流量。
    • @lan Campebell:如何实现自动化,正如我在问题中提到的那样,为了简单起见,我只提到了一个 uid,但在实际数据框中,我有 ~10000 个唯一的 uid,我不会无法为所有人手动设置“startingbalance”。
    • @lan Campebell:再次感谢,需要您的建议以使其自动化为 ~10000 uid。
    • Campebell:用 Input dput 和 output dput 更新了问题。
    • 我发现,数据集中有问题。一个 uid 具有不同的计算,因此它显示错误。我在 dput 中更新了一个简单的 2 uid。请试一试...另外,请评论代码,这样对我解决任何问题非常有帮助。
    猜你喜欢
    • 2022-11-18
    • 1970-01-01
    • 2015-12-11
    • 2020-12-28
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    相关资源
    最近更新 更多