【问题标题】:Financial Data - R data.table - group by condiction财务数据 - R data.table - 按条件分组
【发布时间】:2015-05-12 02:37:30
【问题描述】:

给定以下data.table 的财务数据:

userId  systemBankId    accountId   valueDate   quantity    description
871     0065            6422        2013-02-28  -52400      AMORTIZACION PRESTAMO       
871     0065            6422        2013-03-28  -52400  AMORTIZACION PRESTAMO   
871     0065            6422        2013-04-01  -3000000    AMORTIZACION PRESTAMO
871     0065            6422        2013-04-30  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2013-05-31  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2013-06-28  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2013-07-30  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2013-08-30  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2013-09-30  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2013-10-30  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2013-11-29  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2013-12-30  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2014-01-30  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2014-02-28  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2014-03-31  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2014-04-30  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2014-05-30  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2014-06-30  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2014-07-30  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2014-08-29  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2014-09-30  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2014-10-30  -52349  AMORTIZACION PRESTAMO   
871     0065            6422        2014-11-28  -52349  AMORTIZACION PRESTAMO

我想按userIdsystemBankIdaccountIdquantity 分组:

dt[userId==871L,.N,by=.(userId,systemBankId,accountId,quantity)]

结果如下:

   userId systemBankId accountId quantity  N
   871         0065      6422   -52400     3
   871         0065      6422 -3000000     1
   871         0065      6422   -52349    20

但是,第一个和第三个是同一个交易:按揭付款,第二个是贷款。

我想按以下方式分组:

userId systemBankId accountId quantity N
   871         0065      6422   -XXXXX 23
   871         0065      6422 -3000000  1

所以你可以看到这个用户在 24 个月内有 23 笔抵押交易和 1 笔贷款交易付款。

问题是:有简单的方法吗? (即):

dt[userId==871L,.N,by=.(userId,systemBankId,accountId,(quantity %between% c(-quantity*0.20,quantity*0,20 ))]

对于范围 [-20%,20%] 之间的付款被视为相等。

先谢谢你了。

最好的问候。


获取上面数据的数据框:

structure(list(userId = c(871L, 871L, 871L, 871L, 871L, 871L, 
871L, 871L, 871L, 871L, 871L, 871L, 871L, 871L, 871L, 871L, 871L, 
871L, 871L, 871L, 871L, 871L, 871L), systemBankId = c(65L, 65L, 
65L, 65L, 65L, 65L, 65L, 65L, 65L, 65L, 65L, 65L, 65L, 65L, 65L, 
65L, 65L, 65L, 65L, 65L, 65L, 65L, 65L), accountId = c(6422L, 
6422L, 6422L, 6422L, 6422L, 6422L, 6422L, 6422L, 6422L, 6422L, 
6422L, 6422L, 6422L, 6422L, 6422L, 6422L, 6422L, 6422L, 6422L, 
6422L, 6422L, 6422L, 6422L), valueDate = structure(c(2L, 4L, 
1L, 10L, 23L, 5L, 14L, 16L, 17L, 19L, 8L, 21L, 9L, 3L, 22L, 11L, 
12L, 13L, 15L, 7L, 18L, 20L, 6L), .Label = c("01/04/2013", "28/02/2013", 
"28/02/2014", "28/03/2013", "28/06/2013", "28/11/2014", "29/08/2014", 
"29/11/2013", "30/01/2014", "30/04/2013", "30/04/2014", "30/05/2014", 
"30/06/2014", "30/07/2013", "30/07/2014", "30/08/2013", "30/09/2013", 
"30/09/2014", "30/10/2013", "30/10/2014", "30/12/2013", "31/03/2014", 
"31/05/2013"), class = "factor"), quantity = c(-52400L, -52400L, 
-3000000L, -52349L, -52349L, -52349L, -52349L, -52349L, -52349L, 
-52349L, -52349L, -52349L, -52349L, -52349L, -52349L, -52349L, 
-52349L, -52349L, -52349L, -52349L, -52349L, -52349L, -52349L
), description = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "AMORTIZACION PRESTAMO", class = "factor")), .Names = c("userId", 
"systemBankId", "accountId", "valueDate", "quantity", "description"
), class = "data.frame", row.names = c(NA, -23L))

U P D A T E

最后一步是在原始数据集中标记按揭付款和贷款付款的交易。

根据我的回答:

a) 标准:在 24 个月的时间段内,如果 userId、systemBankId、accountId、数量 (-20%,20%) 有 20 次或更多经常性交易,则它们是抵押付款:

tmp <- dt[userId==871L,.N,by=.(userId,systemBankId,accountId,round(quantity * 5, -floor(log10(abs(quantity))))/5)][N>20,list(userId,systemBankId,accountId,round,N)]

userId systemBankId accountId  round  N
871         0065      6422    -52000 23

我知道有 23 笔抵押交易。

b) 我需要识别这 23 笔交易:

tmp2 <- dt[userId==871L,list(userId,systemBankId,accountId,round=round(quantity * 5, -floor(log10(abs(quantity))))/5)]

merge(tmp,tmp2,by=c('userId','systemBankId','accountId','round'))

   userId systemBankId accountId  round  N
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
   871         0065      6422 -52000 23
userId systemBankId accountId  round  N

好的,我已经确定了 23 笔交易,但如果我有一笔交易数量等于 -52000,这也将被标记为抵押付款。

我的问题是:基于定期付款的标准,我如何识别正确的交易。

谢谢。

【问题讨论】:

  • 在您的示例中,您只有 2 个 -52400 数量,而不是 3 个。
  • 类似DT[userId == 871L, .N, by = .(userId, systemBankId, accountId, quantity = round(quantity * 5, -floor(log10(abs(quantity))))/5)]?
  • @Roland 你应该把它作为答案发布

标签: r data.table grouping self-join


【解决方案1】:

也许是这样的:

dt[, round.qty := quantity[1] * round(quantity/quantity[1]), by = .(userId, systemBankId, accountId)]

dt[, .N, by = .(userId, systemBankId, accountId, round.qty)]
#   userId systemBankId accountId round.qty  N
#1:    871           65      6422    -52400 22
#2:    871           65      6422  -2986800  1

【讨论】:

    【解决方案2】:

    这是dplyr 的快速破解:

    library(dplyr)
    setDF(dt) %>% mutate(quantity =  round(quantity/10000, 0)) %>%
      group_by(userId, systemBankId, accountId, quantity) %>% tally()
    

    这给出了:

    #Source: local data frame [2 x 5]
    #Groups: userId, systemBankId, accountId
    #
    #  userId systemBankId accountId quantity  n
    #1    871           65      6422     -300  1
    #2    871           65      6422       -5 22
    

    编辑

    正如大卫在 cmets 中提到的,这个答案过于简单化了。更一致的方法是类似于 Roland 的建议:

    library(dplyr)
    setDF(dt) %>% 
      mutate(quantity = round(quantity * 5, -floor(log10(abs(quantity))))/5) %>%
      group_by(userId, systemBankId, accountId, quantity) %>% tally()
    

    或者使用data.table:

    dt[userId == 871L, .N, by = .(userId, systemBankId, accountId, quantity = round(quantity * 5, -floor(log10(abs(quantity))))/5)]
    

    【讨论】:

    • 不知道为什么不能将 OP 代码稍微修改为 dt[userId==871L,.N,by=.(userId,systemBankId,accountId, quantity = round(quantity/10000, 0))],为什么是 dplyr
    • [-20%,20%] 被认为是相等的事实呢
    • 这个答案在概念上也是错误的,因为您假设抵押贷款支付为 1 万。尝试dt[, quantity := quantity*100],然后再次运行您的代码,看看会发生什么。
    【解决方案3】:

    这是@dnlbrky 在此处创建的相关巧妙功能:Use a value from the previous row in an R data.table calculation

    #Create a function to return previous rows 
       rowShift <- function(x, shiftLen = 1L) {
         r <- (1L + shiftLen):(length(x) + shiftLen)
         r[r<1] <- NA
         return(x[r])
       }
    

    这将让您确定 20% 的范围:

    dt$prev_qty_low  <-rowShift(dt$quantity,-1) * .8
    dt$prev_qty_high <-rowShift(dt$quantity,-1) * 1.2
    

    【讨论】:

      猜你喜欢
      • 2013-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-15
      • 1970-01-01
      相关资源
      最近更新 更多