2015-01-23 3 views
3

데이터 테이블을 사용하여 R에서 상환 대출 계좌 모델을 만들려고합니다. 각 행은 한 달을 나타냅니다. 매달 기금의 상환 또는 상환 및 전월 잔액에 대한이자 부담이 있습니다. 예를 들어롤링 계산 R

: 나는 관심과 균형 열을 추가하는 쉬운 방법을 볼 수 없습니다

> loan <- data.table(loan.age = seq(0:9), payment = c(5000, -rep(100,9))) 

. 한 달에 1 %의 이자율을 적용한 경우이자는 전월 잔액의 0.01 배이어야하며 새 잔액은 전월의 잔액에 당월의이자 + 현재 달의이자를 더한 금액이어야합니다 (일반적으로 부정적입니다). 의사 코드에서 :

this_balance = last_balance + last_balance * 0.01 + this_payment 

이것은 내가 찾고 결과입니다

> loan 
    loan.age payment interest balance 
1:  0 5000  0.00 5000.00 
2:  1 -100 50.00 4950.00 
3:  2 -100 49.50 4899.50 
4:  3 -100 48.99 4848.49 
5:  4 -100 48.49 4796.98 
6:  5 -100 47.97 4744.95 
7:  6 -100 47.45 4692.40 
8:  7 -100 46.92 4639.32 
9:  8 -100 46.39 4585.71 
10:  9 -100 45.87 4531.58 

내가 for 루프의 문제를 해결할 수 있지만, 큰 포트폴리오를 통해 unworkably 느리다. 상황에 따라 300 개월 대출은 연금 수식을 for for 루프 (대출 당 2 대 20ms)보다 100 배 빠릅니다.

나는 테이블 자체에 조인을 시도했고 데이터 테이블 1.9.5에서 새로운 shift() 함수도 시도했지만 계산을 강제로 수행하는 방법은 없다. 새로운 균형이 테이블 아래로 물결 치게하기 위해 위에서 아래로.

내 코드는 현재 연금 수식에서 파생 된 일부 재무 계산을 사용하여 각 기간의 잔액을 계산하지만 금리가 대출을 통해 부분적으로 변경되는 경우 해당 방법이 작동하지 않습니다.

감사합니다.

편집 : 나는이 문제를 해결한다. Solution 2b) from G. 아래의 Grothendieck은이 간단한 경우에 모두 작동하며보다 복잡한 시나리오로 확장 할 수있는 일반적인 솔루션을 제공합니다.

+0

'interest' 열과 관련하여 공식이 있습니까? – akrun

+0

"이자는 전월 잔액의 0.01 배가되어야하며 잔액은 전월 잔액과 당월이자를 합한 금액이어야합니다." 그것은 귀하의 예에서는 그렇지 않습니다. 고쳐주세요. – Roland

+0

혼란을 가져 주어서 죄송합니다 - 실제 사례는 정확하지만 내러티브는 불완전합니다. 설명을 수정하고 수학 코드의 작동 방식을 보여주는 가상 코드 행을 추가했습니다. –

답변

8

1)filter보십시오 :

loan[, c("interest", "balance") := 0][, 
    balance := c(filter(payment, 1.01, method = "recursive"))][, 
    interest := c(0, diff(balance) - payment[-1])] 

제공 :

> loan 
    loan.age payment interest balance 
1:  1 5000 0.00000 5000.000 
2:  2 -100 50.00000 4950.000 
3:  3 -100 49.50000 4899.500 
4:  4 -100 48.99500 4848.495 
5:  5 -100 48.48495 4796.980 
6:  6 -100 47.96980 4744.950 
7:  7 -100 47.44950 4692.399 
8:  8 -100 46.92399 4639.323 
9:  9 -100 46.39323 4585.716 
10:  10 -100 45.85716 4531.574 

참고 : 마지막 줄이 교대로 기록 될 수있다 :

  interest := .01 * c(0, balance[-.N])] 

또는 개발 V data.table의 ersion :

  interest := .01 * shift(balance, fill = 0)[[1]]] 

2) 축소 다른 가능성은 :

f <- function(balance, payment) payment + 1.01 * balance 

loan[, c("interest", "balance") := 0][, 
    balance := Reduce(f, payment, accumulate = TRUE) ][, 
    interest := c(0, diff(balance) - payment[-1]) ] 

2A) 또는 거기 rate 열이며 payment는 제외 일정하다고 알려져 있다면 첫 번째 가치 (질문에서와 같이) 다음 작품.

loan$rate <- .01 
g <- function(balance, rate) loan$payment[2] + (1 + rate) * balance 

loan[, c("interest", "balance") := 0][, 
    balance := Reduce(g, rate[-1], init = payment[1], accumulate = TRUE) ][, 
    interest := c(0, diff(balance) - payment[-1]) ] 

2B)이 모두 paymentrate는 다양 할 수 있습니다 : 우리는 rate 열 일정을 만들었습니다하지만, 다음은 여전히 ​​rate는 상수 payment의 가정만큼 변화 보유하는 경우에도 작동합니다

loan$rate <- .01 
h <- function(balance, i) loan$payment[i] + (1 + loan$rate[i]) * balance 

loan[, c("interest", "balance") := 0][, 
    balance := Reduce(h, .I[-1], init = payment[1], accumulate = TRUE) ][, 
    interest := c(0, diff(balance) - payment[-1]) ] 
+0

: = 연산자 란 무엇입니까? – Rodrigo

+0

data.table의 일부입니다. R,'library (data.table); help (": =")' –

+0

제가 설명했던 간단한 경우에 정말 잘 작동합니다. 그러나 이자율에 대한 란을 추가하여 대출 기간 동안 이자율을 변경할 수 있도록하고 싶습니다. 두 번째 인수로 벡터의 각 요소를 대출의 각 요소에 적용하지 않기 때문에 필터를 사용하여이를 달성 할 수있는 방법이 없습니다. –