根据Australia's marginal tax rates,我正在编写一个函数来根据收入水平计算欠税。
我写了一个简单的函数版本,使用以下内容可以获得正确的税额:
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)
}
我的问题是,在数据编码时,我无法概念化或编码如何产生欠税额和边际费率。
答案 0 :(得分:10)
这是一个实现这一诀窍的单线:
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 :(得分:3)
我认为您正在寻找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
您只需在brackets
所属的每个元素之间找到,并将其用作rates
和{{1}}的索引。我还将值作为参数添加到默认值。
答案 2 :(得分:1)
我略微更改了您的brackets
和rates
参数。您可以使用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