2015-11-18 11 views
11

Australia's marginal tax ratesに従った所得水準の税金を計算する関数を書いています。限界税率の計算R

私は、以下のものを使用して支払うべき税額の正確な量になり、関数の簡易版書いた:

income_tax <- function(income) { 
# Calculate income tax liability based on income 
# 
# Returns the amount of income tax owed 

    if (income > 0 & income <= 18200) { 
     tax <- 0 
     } else if (income > 18200 & income <= 37000) { 
     tax <- (income - 18200) * .19 
     } else if (income > 37000 & income <= 80000) { 
     tax <- 3572 + (income - 37000) * .325 
     } else if (income > 80000 & income <= 180000) { 
     tax <- 17547 + (income - 80000) * .37 
     } else if (income > 180000) { 
     tax <- 54547 + (income - 180000) * .45 
     } 
    return(tax) 
} 

をこのアプローチの問題は、私は速度をハードコーディングされたことで、各ブラケットでロジックに支払われた金額。これは関数を壊れやすくし、異なるレートや括弧をテストすることができないことを意味します(これが私の最終目標です)。

私がしたいのは、税率表からロジックを生成することです。

ここでは、擬似コードで記述されたアルゴリズムをコメントとして使用したいと思っているバージョンを示します。

income_tax <- function(income) { 
# Calculate income tax liability based on income 
# 
# Returns the amount of income tax owed 
brackets <- c(18200,37001,80000,180000,180000) 
rates <- c(0,.19,.325,.37,.45) 
tax_rates <- data.frame(brackets, rates) 

for (i in 1:nrow(tax_rates)) { 
    # if income is in bracket_X then: 
    # tax <- (income - bracket_X[i-1]) * rate_X + minimum_tax_from_bracket_X[-1] 
    } 

return(tax) 
} 

私の問題は、私は概念化やデータは次のようにエンコードされている間負っ税と限界税率の量を生成するための方法をコードすることができないということです。

答えて

7

は、トリックを行いワンライナーです:

income_tax <- 
function(income, 
     brackets = c(18200, 37000, 80000, 180000, Inf), 
     rates = c(0, .19, .325, .37, .45)) {   
    sum(diff(c(0, pmin(income, brackets))) * rates) 
} 

おそらくそれがどのように動作するか/なぜ見るための最も簡単な方法は、このように、いくつかの単純なパラメータを使用して、ロジックのコアビットをいじっすることです:

brackets <- c(1:5, Inf) 

diff(c(0, pmin(.35, brackets))) 
## [1] 0.35 0.00 0.00 0.00 0.00 0.00 
diff(c(0, pmin(3.9, brackets))) 
## [1] 1.0 1.0 1.0 0.9 0.0 0.0 
diff(c(0, pmin(99, brackets))) 
## [1] 1 1 1 1 1 94 
+1

私はこれを最も簡単なものとして与えていますし、pminとdiffの2つの関数についても教えています。他の答えも使えますが、これは最もエレガントです。 –

1

bracketsratesのパラメータを少し変更しました。 whileループを使用してこの問題を解決できます。

income_tax <- function(income, 
    brackets = c(18200,37001,80000,180000), 
    rates = c(.19,.325,.37,.45)) 
{ 
    nbrackets <- length(brackets) 
    if(income<=brackets[1]) 
    return(0) 

    i <- 2 
    cumtax <- 0 
    while(i <= nbrackets) { 
    if(income > brackets[i-1] && income < brackets[i]) 
     return(cumtax + rates[i-1]*(income-brackets[i-1])) 
    else 
     cumtax <- cumtax + rates[i-1]*(brackets[i]-brackets[i-1]) 
     i <- i + 1 
    } 
    # income > brackets[nbrackets] 
    cumtax + rates[nbrackets] * (income - brackets[nbrackets]) 
} 

incomes <- seq(0,200000,25000) 
round(sapply(incomes,income_tax),0) 
# [1]  0 1292 7797 15922 24947 34197 43447 52697 63547 
+0

これはうまくいきますが、findIntervalの回答は問題をよりエレガントにするようです。 –

3

私はあなたがfindIntervalを探していると思う:

income_tax <- function(income, 
         brackets = c(0, 18200, 37000, 80000, 180000, 180000), 
         rates = c(0, .19, .325, .37, .45)) { 
    bracketInd <- findInterval(income, brackets, all.inside = TRUE) 
    plus <- if (bracketInd <= 2) 0 else 
    sum(sapply(bracketInd:3, function(ind) { 
     (brackets[ind] - brackets[ind - 1]) * rates[ind - 1] 
    })) 
    if (length(plus) == 0) plus <- 0 
    tax <- plus + (income - brackets[bracketInd]) * rates[bracketInd] 
    return(tax) 
} 

あなたは自分のincomeは、各要素の間に見つけ、そしてbracketsratesのための指標としてそれを使用します。また、デフォルト値でパラメータとして値を追加しました。ここで

+0

あなたは、 '' brackets''パラメータが変更されたときに '' plus''パラメータを計算する方法を提供していません。これは私の意見では重要な点です。 – nathanesau

+0

また、 '' income''が '' tail(brackets、1) ''を超えた場合、関数は誤って '' NA''を返します。 – nathanesau

+0

@nathanesau 1.これはスケールを連続させる固定値です。それは毎年変わるだけで、実際には他の変数にも依存しますが、その場で計算するよう求めませんでした。 2.それは修正されました。 – Molx