2015-03-10 16 views
6

Do sau data.table với dữ liệu tài chính:Financial Data - R data.table - nhóm bởi condiction

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 

Tôi muốn nhóm bởi userId, systemBankId, accountId, và quantity:

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

Kết quả như sau:

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

Nhưng, đầu tiên và thứ ba là cùng một giao dịch: thanh toán thế chấp và thứ hai là một khoản vay.

Tôi muốn nhóm bởi theo cách thức sau đây:

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

Vì vậy, bạn có thể thấy rằng trong 24 tháng sử dụng này có 23 giao dịch thế chấp và 1 thanh toán giao dịch cho vay.

Câu hỏi đặt ra là: Có cách nào dễ dàng để làm điều đó không? (ví dụ):

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

Để thanh toán giữa phạm vi [-20%, 20%] được coi là bằng.

Cảm ơn bạn đã nâng cao.

Trân trọng.


Để có được khung dữ liệu của các dữ liệu trên:

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)) 

CẬP NHẬT

Bước cuối cùng là để đánh dấu trong tập dữ liệu ban đầu các giao dịch được thanh toán thế chấp và không có nhiều các khoản thanh toán cho vay.

Dựa trên câu trả lời tôi làm:

a) criterio: trong một khoảng thời gian 24 tháng ,, nếu có hai mươi hay nhiều giao dịch tái phát bởi userId, systemBankId, AccountID, số lượng (-20%, 20%) chúng là các khoản thanh toán thế chấp:

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 

Tôi biết có 23 giao dịch thế chấp.

b) Tôi cần phải xác định này 23 giao dịch:

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 

Ok tôi đã xác định được 23 giao dịch nhưng nếu tôi có một transacction với số lượng tương đương với -52000 này sẽ được đánh dấu như đó là một thế chấp thanh toán quá.

Câu hỏi của tôi là: dựa trên tiêu chí thanh toán định kỳ Tôi xác định giao dịch chính xác như thế nào.

Thx nâng cao.

+1

Trong ví dụ của bạn, bạn chỉ có 2 '-52400' số lượng, không 3. –

+5

Something như 'DT [userId == 871L, Đô, bởi =. (userId, systemBankId, accountId, quantity = round (số lượng * 5, -floor (log10 (abs (số lượng))))/5)] '? – Roland

+1

@Roland bạn nên đăng câu trả lời –

Trả lời

4

Có lẽ ai lấy cái gì cùng những dòng này:

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 
4

Dưới đây là một cách nhanh chóng tấn công bằng các dplyr:

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

Mà cho:

#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 

Sửa

Như mentionned David trong các ý kiến, câu trả lời này là một sự đơn giản hóa. Một cách tiếp cận phù hợp hơn sẽ là một cái gì đó giống như gợi ý của Roland:

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

Hoặc sử dụng data.table:

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

Không chắc tại sao không thể sửa đổi một chút mã OP thành 'dt [userId == 871L, .N, bởi =. (UserId, systemBankId, accountId, quantity = round (quantity)/10000, 0))] ', tại sao' dplyr'? –

+0

Điều gì về thực tế là '[-20%, 20%]' được coi là bằng –

+4

Câu trả lời này cũng sai về mặt khái niệm vì bạn giả định rằng các khoản thanh toán morgatge là 10 nghìn. Hãy thử 'dt [, quantity: = quantity * 100]' và sau đó chạy lại mã của bạn và xem điều gì xảy ra. –

0

Đây là một chức năng thông minh có liên quan được tạo ra bởi @dnlbrky đây: 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]) 
    } 

Điều này sẽ cho phép bạn xác định phạm vi 20% của mình:

dt$prev_qty_low <-rowShift(dt$quantity,-1) * .8 
dt$prev_qty_high <-rowShift(dt$quantity,-1) * 1.2 
Các vấn đề liên quan