Australia’s superannuation system offers a number of tax breaks. Relative to most methods of savings, less tax is paid on money contributed to a super fund, and less tax is paid on the earnings. The functions described here attempt to model changes to tax breaks on money contributed to a super fund.
The two tax methods modelled are Superannuation contributions tax concessions and Division 293 tax. The two main outputs are: the extra tax payable by a particular individual (and the symmetric extra revenue), and the number of individuals affected.
To obtain these results (say for 2017-18)
library(grattan)
library(data.table)
if (requireNamespace("taxstats", quietly = TRUE)){
library(taxstats)
sample_files_all <- get_sample_files_all()
} else {
install.packages("taxstats", repos = "https://hughparsonage.github.io/drat/", type = "source")
library(taxstats)
sample_files_all <- get_sample_files_all()
}
library(magrittr)
#' dollar scales
#'
#' @name grattan_dollar
#' @param x A numeric vector
#' @param digits Minimum number of digits after the decimal point. (\code{nsmall} in \code{base::format}).
#' @details Makes negative numbers appear as \eqn{-\$10,000} instead of \eqn{\$-10,000} in \code{scales::dollar}.
#' @export
# from scales
grattan_dollar <- function (x, digits = 0) {
#
nsmall <- digits
commaz <- format(abs(x), nsmall = nsmall, trim = TRUE, big.mark = ",",
scientific = FALSE, digits = 1L)
dplyr::if_else(x < 0,
paste0("\U2212","$", commaz),
paste0("$", commaz))
}
(new_revenue <-
sample_file_1314 %>%
project_to(to_fy = "2017-18") %>%
as.data.table %>%
revenue_from_new_cap_and_div293(new_cap = 25e3, fy.year = "2016-17", new_age_based_cap = FALSE, new_div293_threshold = 250e3))
## [1] 1142555190
paste(grattan_dollar(new_revenue / 1e9), "bn")
## [1] "$1 bn"
(n_affected <-
sample_file_1314 %>%
project_to(to_fy = "2017-18") %>%
as.data.table %>%
n_affected_from_new_cap_and_div293(new_cap = 25e3, fy.year = "2016-17", new_age_based_cap = FALSE, new_div293_threshold = 250e3))
## [1] 531007.6
prettyNum(round(n_affected), big.mark = ",")
## [1] "531,008"
Notes:
fy.year
refers to the year the function takes the tax scales from, not the forecast year. Because we don’t have tax scales for 2017-18 yet, we model using the most recent (2017-18
).data.table
s. Sorry if you don’t like data.table
s.sample_file_1314
(because they have superannuation contributions variables).Let’s create an object for sample_file_1718
avoid recreating it every time:
sample_file_1718 <-
sample_file_1314 %>%
project_to(to_fy = "2017-18") %>%
as.data.table
The functions mentioned earlier return single values. In contrast, model_new_caps_and_div293
returns the sample file with extra variables, which can then be analyzed as a standard sample file. The variables of note are prv_revenue
which is the tax payable under the old system, and new_revenue
which is the tax payable under the proposed system. Thus:
new_sample_file_1718 <-
sample_file_1718 %>%
model_new_caps_and_div293(new_cap = 25e3, fy.year = "2016-17", new_age_based_cap = FALSE, new_div293_threshold = 250e3)
library(knitr)
library(dplyr)
library(dtplyr) # for data.table
new_sample_file_1718 %>%
group_by(Taxable_Income_decile = ntile(Taxable_Income, 10)) %>%
summarise(`Average increase in tax` = round(mean(new_revenue - prv_revenue), 2)) %>%
arrange(Taxable_Income_decile) %>%
kable
Taxable_Income_decile | Average increase in tax |
---|---|
1 | 2.04 |
2 | 4.71 |
3 | 12.12 |
4 | 24.52 |
5 | 33.09 |
6 | 33.14 |
7 | 40.31 |
8 | 62.61 |
9 | 98.65 |
10 | 484.97 |
library(ggplot2)
new_sample_file_1718 %>%
group_by(Taxable_Income_decile = ntile(Taxable_Income, 10)) %>%
summarise(`Average increase in tax` = mean(new_revenue - prv_revenue)) %>%
arrange(Taxable_Income_decile) %>%
#
mutate(`Taxable income decile` = factor(Taxable_Income_decile)) %>%
ggplot(aes(x = `Taxable income decile`, y = `Average increase in tax`)) +
geom_bar(stat = "identity") +
# cosmetic:
scale_y_continuous(label = grattan_dollar) +
theme(axis.title.y = element_text(face = "bold", angle = 90, margin = margin(1, 1, 1, 1, "lines")))