I'm writing a function to calculate tax owed given a level of income according to Australia's marginal tax rates.
I've written a simple version of the function that results in the correct amount of tax owed using the following:
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)
}
The problem with this approach is that I've hard-coded the rates and the amount paid in each bracket into the logic. This makes the function fragile, and means I can't test out different rates or brackets (which is my ultimate aim).
What I'd like to do is have the logic generated from a tax rates table.
Here's a version of what I'd like to do with the alorithm written in pseudo code as a comment.
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)
}
My problem is that I can't conceptualise or code how to generate the amount of tax owed and the marginal rates while the data is encoded like this.
By contrast, a taxpayer's marginal tax rate is the tax rate imposed on their “last dollar of income.” For example, a taxpayer with a taxable income of $24,750 will pay 10 percent in taxes on income up to $19,900, and 12 percent on the remaining $5,000 as a portion of the income falls into the 12 percent bracket.
Taxpayers pay less in lower income brackets, more in higher brackets, which is called a marginal tax rate. Every dollar they earn above their current bracket is taxed at the next one. The average tax rate equals total taxes divided by total taxable income.
One method you can always use is to calculate your tax both ways, either considering the anticipated income from the proposed investment or excluding it. Divide the difference in tax by the amount of income from the investment, and you'll get the economic marginal tax rate from investing.
Tax brackets are the income cutoff points before your income causes you to move into a higher or lower tax rate bracket. The marginal tax rate is the rate at which you pay taxes on your last dollar earned.
Here's a one-liner that does the trick:
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)
}
Perhaps the easiest way to see how/why it works is to play around with the core bit of logic with some simpler parameters, like this:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With