├── data ├── finc07.xls ├── pinc11_1.xls └── pinc11_2.xls ├── img ├── png │ ├── family.png │ ├── pooled.png │ ├── split.png │ ├── bachelors.png │ ├── bernietax.png │ ├── business.png │ ├── realrates.png │ ├── billionaires.png │ ├── singlemoms.png │ ├── topmarginal.png │ ├── barplot_family.png │ ├── barplot_pooled.png │ ├── barplot_split.png │ ├── bernieBillions.png │ ├── bernieEmployer.png │ ├── realrates_raw.png │ ├── barplot_bachelor.png │ ├── barplot_business.png │ ├── barplot_emptynest.png │ ├── bernieTax_color.png │ ├── topmarginal_raw.png │ ├── barplot_billionaire.png │ └── barplot_singlemoms.png └── psd │ ├── barplot.psd │ ├── family.psd │ ├── pooled.psd │ ├── split.psd │ ├── bachelors.psd │ ├── business.psd │ ├── realrates.psd │ ├── billionaires.psd │ ├── singlemoms.psd │ └── topmarginal.psd ├── bernietax_example.png ├── bernietax.Rproj ├── license.txt ├── R ├── scripts │ ├── plotsForBBBpost.R │ ├── bernietax.R │ ├── berniePooledTax.R │ └── voxPlots.R ├── plots │ ├── OtherPlotVersions.R │ ├── bernieEmployer.R │ ├── bernieBillions.R │ ├── berniePooledPlot.R │ ├── berniePlotSingle.R │ ├── berniePlotSingleF.R │ ├── berniePlot.R │ └── barStylePlot.R └── functions │ ├── bernietaxFunctions.R │ └── bernieTaxBrackets.R ├── README.md └── BernieTaxExport.csv /data/finc07.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/data/finc07.xls -------------------------------------------------------------------------------- /data/pinc11_1.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/data/pinc11_1.xls -------------------------------------------------------------------------------- /data/pinc11_2.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/data/pinc11_2.xls -------------------------------------------------------------------------------- /img/png/family.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/family.png -------------------------------------------------------------------------------- /img/png/pooled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/pooled.png -------------------------------------------------------------------------------- /img/png/split.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/split.png -------------------------------------------------------------------------------- /img/psd/barplot.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/psd/barplot.psd -------------------------------------------------------------------------------- /img/psd/family.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/psd/family.psd -------------------------------------------------------------------------------- /img/psd/pooled.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/psd/pooled.psd -------------------------------------------------------------------------------- /img/psd/split.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/psd/split.psd -------------------------------------------------------------------------------- /bernietax_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/bernietax_example.png -------------------------------------------------------------------------------- /img/png/bachelors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/bachelors.png -------------------------------------------------------------------------------- /img/png/bernietax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/bernietax.png -------------------------------------------------------------------------------- /img/png/business.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/business.png -------------------------------------------------------------------------------- /img/png/realrates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/realrates.png -------------------------------------------------------------------------------- /img/psd/bachelors.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/psd/bachelors.psd -------------------------------------------------------------------------------- /img/psd/business.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/psd/business.psd -------------------------------------------------------------------------------- /img/psd/realrates.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/psd/realrates.psd -------------------------------------------------------------------------------- /img/png/billionaires.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/billionaires.png -------------------------------------------------------------------------------- /img/png/singlemoms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/singlemoms.png -------------------------------------------------------------------------------- /img/png/topmarginal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/topmarginal.png -------------------------------------------------------------------------------- /img/psd/billionaires.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/psd/billionaires.psd -------------------------------------------------------------------------------- /img/psd/singlemoms.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/psd/singlemoms.psd -------------------------------------------------------------------------------- /img/psd/topmarginal.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/psd/topmarginal.psd -------------------------------------------------------------------------------- /img/png/barplot_family.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/barplot_family.png -------------------------------------------------------------------------------- /img/png/barplot_pooled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/barplot_pooled.png -------------------------------------------------------------------------------- /img/png/barplot_split.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/barplot_split.png -------------------------------------------------------------------------------- /img/png/bernieBillions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/bernieBillions.png -------------------------------------------------------------------------------- /img/png/bernieEmployer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/bernieEmployer.png -------------------------------------------------------------------------------- /img/png/realrates_raw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/realrates_raw.png -------------------------------------------------------------------------------- /img/png/barplot_bachelor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/barplot_bachelor.png -------------------------------------------------------------------------------- /img/png/barplot_business.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/barplot_business.png -------------------------------------------------------------------------------- /img/png/barplot_emptynest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/barplot_emptynest.png -------------------------------------------------------------------------------- /img/png/bernieTax_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/bernieTax_color.png -------------------------------------------------------------------------------- /img/png/topmarginal_raw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/topmarginal_raw.png -------------------------------------------------------------------------------- /img/png/barplot_billionaire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/barplot_billionaire.png -------------------------------------------------------------------------------- /img/png/barplot_singlemoms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmurphyrd/BernieTax/HEAD/img/png/barplot_singlemoms.png -------------------------------------------------------------------------------- /bernietax.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 datatitian.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /R/scripts/plotsForBBBpost.R: -------------------------------------------------------------------------------- 1 | source("R/plots/barStylePlot.R") 2 | 3 | extraIncomes <- c(2000000, 10000000, 50000000, 1000000000) 4 | margins <- grid::unit(c(2.7,2.1,2.5,.25), "lines") 5 | w <- 800 6 | h <- 1037 7 | 8 | #single moms plot final 9 | png("img/png/barplot_singlemoms.png", w, h) 10 | barStylePlot("Single", 1, "F", "ignore") + 11 | coord_flip(ylim = c(0, .5), xlim = c(1.7, 7.2)) + 12 | labs(x = "", y = "", title = "") + 13 | theme(legend.position = "none", 14 | plot.margin = margins) 15 | dev.off() 16 | 17 | #bachelors plot final 18 | png("img/png/barplot_bachelor.png", w, h) 19 | barStylePlot("Single", 0, "M", "ignore") + 20 | coord_flip(ylim = c(0, .5), xlim = c(1.7, 8.1)) + 21 | labs(x = "", y = "", title = "") + 22 | theme(legend.position = "none", 23 | plot.margin = margins) 24 | dev.off() 25 | 26 | #billionaires plot 27 | png("img/png/barplot_billionaire.png", w, h) 28 | barStylePlot("Married/Joint", 2, "M", "ignore", extraIncomes) + 29 | coord_flip(ylim = c(0, .63), xlim = c(4.5, 10.2)) + 30 | labs(x = "", y = "", title = "") + 31 | theme(legend.position = "none", 32 | plot.margin = margins) 33 | dev.off() 34 | 35 | #businesses plot 36 | png("img/png/barplot_business.png", w, h) 37 | barStylePlot("Married/Joint", 2, "M", "isolate") + 38 | coord_flip(ylim = c(0, .5), xlim = c(1.5, 7.15)) + 39 | labs(x = "", y = "", title = "") + 40 | theme(legend.position = "none", 41 | plot.margin = margins) 42 | dev.off() 43 | 44 | #pooled plot 45 | png("img/png/barplot_pooled.png", w, h) 46 | barStylePlot("Married/Joint", 2, "M", "pool", extraIncomes) + 47 | coord_flip(ylim = c(0, .65), xlim = c(2.6, 10.05)) + 48 | labs(x = "", y = "", title = "") + 49 | theme(legend.position = "none", 50 | plot.margin = margins) 51 | dev.off() 52 | 53 | 54 | #family rehash plot 55 | png("img/png/barplot_family.png", w, h) 56 | barStylePlot("Married/Joint", 2, "M", "ignore") + 57 | coord_flip(ylim = c(0, .42), xlim = c(1.7, 7.15)) + 58 | labs(x = "", y = "", title = "") + 59 | theme(legend.position = "none", 60 | plot.margin = margins) 61 | dev.off() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Just How Much Will Bernie Tax Me? 2 | This project compiles all of the proposed tax plans from Democratic 3 | Presidential Candidate Senator Bernie Sanders to determine the effective tax 4 | rates for individuals at different outcomes in comparison with current tax laws. 5 | 6 | Update Feb 1st: Support added for all filing types and family sizes. Polished plots included for family of 4, single male, and single female. 7 | 8 | Update Feb 4th: Added berniePooled.R and berniePooledPlot.R for calculations that pool the employee and employer burden together. Also added federal unemploymen tax and corrected some errors in the calculations of the employer-paid taxes. This analysis is flawed in that it suggests any savings that the employer experiences would be visible to the employee in the form of a raise. The result is that it makes the Bernie plan look better for the employee than it realy is for incomes from $34K to $228K. Even though it is flawed, it is presented as an example for many who claim that the two should be pooled. 9 | 10 | Update Feb 11th: New plot making function barStylePlot that takes arguments for filing status, number of kids, and desired treatment of employer contributions. Automatically selects relevant income levels to display and also plots population prevalence of each income level. Output looks best with adjustment by adding coord_flip() with desired x and y ranges. An example (with some manual annotations) is below. 11 | 12 | The following items are included in the 13 | calculations: 14 | 15 | * Federal Income Tax 16 | * Social Security Tax 17 | * Medicare Tax 18 | * Medicare-for-all Tax 19 | * Paid Family Leave Tax 20 | * Average healthcare premium costs 21 | * Average healthcare out of pocket costs 22 | * Employer FICA & FUTA Contributions (optional) 23 | * Employer Medicare-for-all Contribution (optional) 24 | 25 | 26 | The impact of the following [proposals from Bernie Sanders](https://berniesanders.com/issues/how-bernie-pays-for-his-proposals/) is included: 27 | 28 | * Rebuild America Act 29 | * College for All 30 | * Expand and Extend Social Security 31 | * Youth Jobs Program 32 | * Paid Family and Medical Leave 33 | * Protect Pensions 34 | * Renewable Energy and Clean Jobs Transition 35 | * Medicare for All 36 | 37 | Note that impacts on investment earnings are not included in this project. 38 | 39 | ![Comparative Effective Tax Rates](bernietax_example.png) 40 | -------------------------------------------------------------------------------- /R/plots/OtherPlotVersions.R: -------------------------------------------------------------------------------- 1 | 2 | ggplot(filter(datDiff, payer == "Individual"), aes(x = income)) + 3 | geom_segment(aes(xend = income, yend = 0.51, y = .2), percentiles, 4 | linetype = 2, color = "grey40") + 5 | geom_ribbon(aes(ymax = iTop, ymin = iBottom, fill = "Increase")) + 6 | geom_ribbon(aes(ymax = dTop, ymin = dBottom, fill = "Decrease")) + 7 | # geom_line(aes(y = eTax - .0025, x = income * 1.03, group = set), datSum, 8 | # size = 2, color = "grey20") + 9 | geom_line(aes(y = eTaxBern, color = "Bernie"), size = 1.9) + 10 | geom_line(aes(y = eTaxCur, color = "Current"), size = 1.9) + 11 | scale_x_log10(breaks = percentiles$income, labels = percentiles$xlabs) + 12 | scale_y_continuous(labels = scales::percent) + 13 | scale_color_manual("Tax Plan", values = c("#287CBF", "#EB514F")) + 14 | scale_fill_manual("Change under Bernie's Plans", 15 | values = c("#7db6e3", "#f18b89")) + 16 | theme_classic() + 17 | theme(axis.line = element_blank(), legend.position = "bottom") 18 | 19 | #stat_smooth(aes(y = centile), acs, se = F, method = loess) + 20 | #coord_cartesian(xlim = c(min(incomes), max(incomes))) 21 | 22 | 23 | # distrPlot <- ggplot(acs, aes(x = Dollars, y = Number)) + 24 | # stat_smooth(se = F, method = loess) + 25 | # coord_cartesian(xlim = c(min(incomes), max(incomes))) + 26 | # theme_classic() + 27 | # theme(axis.line = element_blank()) 28 | # 29 | # lay <- rbind(1, 1, 2) 30 | # grid.arrange(taxPlots, distrPlot, layout_matrix = lay) 31 | 32 | ggplot(datDiff, aes(x = income)) + 33 | geom_ribbon(aes(ymax = iTop, ymin = iBottom, fill = "Increase")) + 34 | geom_ribbon(aes(ymax = dTop, ymin = dBottom, fill = "Decrease")) + 35 | geom_line(aes(y = eTax - .0025, x = income * 1.03, group = set), datSum, 36 | size = 2, color = "grey20") + 37 | geom_line(aes(y = eTax, color = set), datSum, size = 1.9) + 38 | facet_grid(payer ~ ., scales = "free") + 39 | scale_x_continuous(labels = scales::dollar) + 40 | scale_y_continuous(labels = scales::percent) + 41 | scale_color_manual("Tax Plan", values = c("#287CBF", "#EB514F")) + 42 | scale_fill_manual("Change under Bernie's Plans", 43 | values = c("#7db6e3", "#f18b89")) + 44 | theme_classic() + 45 | theme(axis.line = element_blank()) + 46 | stat_smooth(aes(y = centile), acs, se = F, method = loess) + 47 | coord_cartesian(xlim = c(min(incomes), max(incomes))) 48 | -------------------------------------------------------------------------------- /R/plots/bernieEmployer.R: -------------------------------------------------------------------------------- 1 | shadowOffsetX <- .002 2 | shadowOffsetY <- -.002 3 | shadowSize <- 2.5 4 | shadowColor <- c("grey30", "grey30") 5 | #line colors bernie, current 6 | #trendColors <- c("#287CBF", "#44445c") 7 | trendColors <- c("#2d8cd8", "#48476f") 8 | 9 | 10 | #fill colors savings, increase 11 | #fillColors <- c("#1FC77F", "#FFB450") 12 | fillColors <- c("#21DC91", "#FF9400") 13 | png("bernieEmployer.png", width = 1024, height = 768) 14 | #minor tweek to keep distinct fill regions from reaching across the graph to 15 | #connect with each other 16 | mutate_each(datDiff, funs(ifelse(is.na(.), 0.1216513, .)), starts_with("i"), 17 | starts_with("d")) %>% 18 | ggplot(aes(x = percentile)) + 19 | facet_grid(payer ~ .) + 20 | geom_ribbon(aes(ymax = iTop, ymin = iBottom, fill = "Increase")) + 21 | geom_ribbon(aes(ymax = dTop, ymin = dBottom, fill = "Savings")) + 22 | geom_line(aes(y = eTaxBern + shadowOffsetY , x = percentile + shadowOffsetX), 23 | size = shadowSize, color = shadowColor[1]) + 24 | geom_line(aes(y = eTaxCur + shadowOffsetY, x = percentile + shadowOffsetX), 25 | size = shadowSize, color = shadowColor[2]) + 26 | geom_line(aes(y = eTaxBern, color = "Bernie"), size = 2.75) + 27 | geom_line(aes(y = eTaxCur, color = "Current"), size = 2.75) + 28 | scale_x_continuous(breaks = c(.05, .25, .5, .75, .95), 29 | labels = centileLabeler) + 30 | scale_y_continuous(labels = scales::percent) + 31 | scale_color_manual("Tax Plan", values = trendColors) + 32 | scale_fill_manual("Change under Bernie's Plans", 33 | limits = c("Savings", "Increase"), 34 | values = fillColors) + 35 | guides(color = guide_legend(order = 1)) + 36 | theme(axis.line = element_blank(), 37 | legend.position = "bottom", 38 | text = element_text(size = 24), 39 | axis.title.y = element_text(margin = margin(0, 15, 0, 0)), 40 | axis.title.x = element_text(margin = margin(15, 0, 0, 0)), 41 | plot.title = element_text(margin = margin(0, 0, 30, 0), size = 40), 42 | panel.grid.major.x = 43 | element_line(colour = "grey80", size = 1, linetype = 2), 44 | panel.background = element_blank(), 45 | axis.ticks.x = element_blank()) + 46 | labs(y = "Tax and Healthcare Burden (% of income)", 47 | x = "Income for a Family of 4 (USD)", 48 | title = "Just How Much Would Bernie Sanders Tax Me?") #+ 49 | 50 | 51 | dev.off() -------------------------------------------------------------------------------- /R/plots/bernieBillions.R: -------------------------------------------------------------------------------- 1 | shadowOffsetX <- .002 2 | shadowOffsetY <- -.002 3 | shadowSize <- 2.5 4 | shadowColor <- c("grey30", "grey30") 5 | #line colors bernie, current 6 | #trendColors <- c("#287CBF", "#44445c") 7 | trendColors <- c("#2d8cd8", "#48476f") 8 | 9 | 10 | #fill colors savings, increase 11 | #fillColors <- c("#1FC77F", "#FFB450") 12 | fillColors <- c("#21DC91", "#FF9400") 13 | #png("bernieBillions.png", width = 1024, height = 768) 14 | ggplot(filter(datDiff, payer == "Individual"), aes(x = income)) + 15 | geom_ribbon(aes(ymax = iTop, ymin = iBottom, fill = "Increase")) + 16 | geom_ribbon(aes(ymax = dTop, ymin = dBottom, fill = "Savings")) + 17 | geom_line(aes(y = eTaxBern, color = "Bernie"), size = 2.75) + 18 | geom_line(aes(y = eTaxCur, color = "Current"), size = 2.75) + 19 | scale_x_log10(breaks = c(60000, 250000, 1000000, 10000000, 50000000), 20 | labels = scales::dollar) + 21 | # scale_x_continuous(breaks = c(.05, .25, .5, .75, .95), 22 | # labels = centileLabeler) + 23 | scale_y_continuous(labels = scales::percent, breaks = seq(-1,1, by = .1)) + 24 | scale_color_manual("Tax Plan", values = trendColors) + 25 | scale_fill_manual("Change under Bernie's Plans", 26 | limits = c("Savings", "Increase"), 27 | values = fillColors) + 28 | #guides(color = guide_legend(order = 1)) + 29 | #guides(color = F, fill = F) + 30 | theme(axis.line = element_blank(), 31 | legend.position = "bottom", 32 | text = element_text(size = 24), 33 | axis.title.y = element_text(margin = margin(0, 15, 0, 0)), 34 | axis.title.x = element_text(margin = margin(15, 0, 0, 0)), 35 | plot.title = element_text(margin = margin(0, 0, 30, 0), size = 36), 36 | panel.grid.major.x = 37 | element_line(colour = "grey80", size = 1, linetype = 2), 38 | panel.background = element_blank(), 39 | axis.ticks.x = element_blank()) + 40 | labs(y = "Tax and Healthcare Burden (% of income)", 41 | x = "Income for a Family of 4 (USD)", 42 | title = "Just How Much Would Bernie Sanders Tax Billionaires?") + 43 | coord_cartesian(xlim = c(20000, 55000000)) 44 | # annotate("text", x = .21, y = .33, 45 | # label = "Taxes + Healthcare Expense Now", 46 | # angle = 0, hjust = 0, color = trendColors[2], size = 12, 47 | # fontface = "bold") + 48 | # annotate("text", x = .23, y = -.19, 49 | # label = "Bernie's Plans for Taxes, Healthcare and More", 50 | # angle = 28, hjust = 0, color = trendColors[1], size = 12, 51 | # fontface = "bold") + 52 | # 53 | # geom_label(aes(y = mid, label = lab, hjust = hjust), data = savings, 54 | # size = 6) 55 | 56 | #dev.off() 57 | 58 | -------------------------------------------------------------------------------- /R/plots/berniePooledPlot.R: -------------------------------------------------------------------------------- 1 | shadowOffsetX <- .002 2 | shadowOffsetY <- -.002 3 | shadowSize <- 2.5 4 | shadowColor <- c("grey30", "grey30") 5 | #line colors bernie, current 6 | #trendColors <- c("#287CBF", "#44445c") 7 | trendColors <- c("#2d8cd8", "#48476f") 8 | 9 | 10 | #fill colors savings, increase 11 | #fillColors <- c("#1FC77F", "#FFB450") 12 | fillColors <- c("#21DC91", "#FF9400") 13 | #png("bernieBillions.png", width = 1024, height = 768) 14 | ggplot(filter(pDatDiff, income >= 40000), aes(x = income)) + 15 | geom_ribbon(aes(ymax = iTop, ymin = iBottom, fill = "Increase")) + 16 | geom_ribbon(aes(ymax = dTop, ymin = dBottom, fill = "Savings")) + 17 | geom_line(aes(y = eTaxBern, color = "Bernie"), size = 2.75) + 18 | geom_line(aes(y = eTaxCur, color = "Current"), size = 2.75) + 19 | scale_x_log10(breaks = c(60000, 250000, 1000000, 10000000, 50000000), 20 | labels = scales::dollar) + 21 | # scale_x_continuous(breaks = c(.05, .25, .5, .75, .95), 22 | # labels = centileLabeler) + 23 | scale_y_continuous(labels = scales::percent, breaks = seq(-1,1, by = .05)) + 24 | scale_color_manual("Tax Plan", values = trendColors) + 25 | scale_fill_manual("Change under Bernie's Plans", 26 | limits = c("Savings", "Increase"), 27 | values = fillColors) + 28 | #guides(color = guide_legend(order = 1)) + 29 | #guides(color = F, fill = F) + 30 | theme(axis.line = element_blank(), 31 | legend.position = "bottom", 32 | text = element_text(size = 24), 33 | axis.title.y = element_text(margin = margin(0, 15, 0, 0)), 34 | axis.title.x = element_text(margin = margin(15, 0, 0, 0)), 35 | plot.title = element_text(margin = margin(0, 0, 30, 0), size = 36), 36 | panel.grid.major.x = 37 | element_line(colour = "grey80", size = 1, linetype = 2), 38 | panel.background = element_blank(), 39 | axis.ticks.x = element_blank()) + 40 | labs(y = "Tax and Healthcare Burden (% of income)", 41 | x = "Income for a Family of 4 (USD)", 42 | title = "Just How Much Would Bernie Sanders Tax Billionaires?") + 43 | coord_cartesian(xlim = c(40000, 55000000)) 44 | # annotate("text", x = .21, y = .33, 45 | # label = "Taxes + Healthcare Expense Now", 46 | # angle = 0, hjust = 0, color = trendColors[2], size = 12, 47 | # fontface = "bold") + 48 | # annotate("text", x = .23, y = -.19, 49 | # label = "Bernie's Plans for Taxes, Healthcare and More", 50 | # angle = 28, hjust = 0, color = trendColors[1], size = 12, 51 | # fontface = "bold") + 52 | # 53 | # geom_label(aes(y = mid, label = lab, hjust = hjust), data = savings, 54 | # size = 6) 55 | 56 | #dev.off() 57 | 58 | -------------------------------------------------------------------------------- /R/scripts/bernietax.R: -------------------------------------------------------------------------------- 1 | library(dplyr); library(tidyr); library(ggplot2); library(readxl) 2 | source("R/functions/bernieTaxBrackets.R") 3 | source("R/functions/bernietaxFunctions.R") 4 | 5 | useCorporateWelfare <- F 6 | writePlotToDisk <- T 7 | #filingStatus <- "Single" 8 | #nKids <- 0 9 | filingStatus <- "Married/Joint" 10 | nKids <- 2 11 | sex <- "M" 12 | 13 | incomes <- seq(8000, 402000, by = 2000) 14 | #incomes <- seq(10000, 50000000, by = 10000) 15 | 16 | acsList <- getCensusIncomes(filingStatus, sex) 17 | acs <- acsList$acs 18 | getIncomeForPercentile <- acsList$getIncomeForPercentile 19 | getPercentileForIncome <- acsList$getPercentileForIncome 20 | centileLabeler <- acsList$centileLabeler 21 | 22 | incomes <- c(incomes, getIncomeForPercentile(c(.25, .5, .75))) 23 | 24 | dat <- taxesByIncomes(incomes, filingStatus, nKids, sex, 25 | useCorporateWelfare = useCorporateWelfare) 26 | 27 | #total effective tax rates 28 | datSum <- dat %>% group_by(payer, set, income, effectiveIncome, agi) %>% 29 | summarize(tTax = sum(amount)) %>% ungroup %>% 30 | mutate(eTax = tTax / effectiveIncome, 31 | payer = factor(payer, levels = c("Individual", "Employer"))) 32 | 33 | 34 | datSum <- mutate(datSum, percentile = getPercentileForIncome(income)) 35 | 36 | #differences between plans / ribbon data 37 | datDiff <- inner_join(filter(datSum, set == "Bernie"), 38 | filter(datSum, set == "Current"), 39 | by = c("payer", "income", "percentile")) %>% 40 | rename(eTaxBern = eTax.x, eTaxCur = eTax.y) %>% 41 | mutate(increase = eTaxBern > eTaxCur, 42 | iTop = ifelse(increase, eTaxBern, NA), 43 | iBottom = ifelse(increase, eTaxCur, NA), 44 | dTop = ifelse(!increase, eTaxCur, NA), 45 | dBottom = ifelse(!increase, eTaxBern, NA)) 46 | 47 | 48 | if(writePlotToDisk) png("img/png/bernieTax_color.png", width = 1024, height = 768) 49 | 50 | if(filingStatus == "Married/Joint") { 51 | source("R/plots/berniePlot.R", print.eval = T) 52 | } else { 53 | if(sex == "M") { 54 | source("R/plots/berniePlotSingle.R", print.eval = T) 55 | } else { 56 | source("R/plots/berniePlotSingleF.R", print.eval = T) 57 | } 58 | } 59 | 60 | if(writePlotToDisk) dev.off() 61 | 62 | 63 | #data table export (not currently working) 64 | # export <- rbind(cur, bern) %>% merge(datSum) 65 | # export <- rename(export, `Total Tax` = tTax, `Effective Tax Rate` = eTax, 66 | # `Income Percentile` = percentile, Income = income) %>% 67 | # select(-agi, -effectiveIncome, -payer) 68 | # export <- merge(filter(export, set == "Bernie") %>% select(-set), 69 | # filter(export, set == "Current") %>% select(-set), 70 | # by = c("Income", "Income Percentile"), 71 | # suffixes = c(" with Bernie", " at Present")) %>% 72 | # arrange(Income) 73 | # 74 | # write.csv(export, "BernieTaxExport.csv", row.names = F) -------------------------------------------------------------------------------- /R/scripts/berniePooledTax.R: -------------------------------------------------------------------------------- 1 | #total effective tax rates with employer contributions 2 | 3 | library(dplyr); library(tidyr); library(ggplot2); library(readxl) 4 | source("R/functions/bernieTaxBrackets.R") 5 | source("R/functions/bernietaxFunctions.R") 6 | 7 | useCorporateWelfare <- F 8 | #filingStatus <- "Single" 9 | #nKids <- 0 10 | filingStatus <- "Married/Joint" 11 | nKids <- 2 12 | sex <- "F" 13 | 14 | taxNamesInd <- c("Income Tax", "Social Security Tax", "Medicare Tax", 15 | "Medicare-for-all Tax", "Family Leave Tax", 16 | "Healthcare Premiums", "Healthcare Expenses") 17 | taxNamesEmp <- c("Employer Healthcare\nContribution", 18 | "Employer Payroll Tax", "Corporate Welfare") 19 | 20 | #incomes <- seq(8000, 402000, by = 2000) 21 | incomes <- seq(10000, 50000000, by = 10000) 22 | 23 | acsList <- getCensusIncomes(filingStatus, sex) 24 | getIncomeForPercentile <- acsList$getIncomeForPercentile 25 | getPercentileForIncome <- acsList$getPercentileForIncome 26 | acs <- acsList$acs 27 | # glm modeling allows for smoother interpolation, but becomes inaccurate 28 | # at extremes. Linear interpolation used instead 29 | # mod <- glm(centile ~ income, acs, family = "binomial") 30 | # getPercentileForIncome <- function(x) { 31 | # predict(mod, data.frame(income = x), type = "response") 32 | # } 33 | 34 | centileLabeler <- acsList$centileLabeler 35 | 36 | incomes <- c(incomes, getIncomeForPercentile(c(.25, .5, .75))) 37 | 38 | totalDeduction <- getDeduction(incomes, filingStatus, nKids) 39 | 40 | brackets <- getBrackets(filingStatus, useCorporateWelfare, nKids) 41 | 42 | 43 | pCur <- taxes(incomes, c(brackets$currentIndBrackets, 44 | brackets$currentEmpBrackets), totalDeduction) %>% 45 | mutate(set = "Current") %>% 46 | applyCredits(filingStatus, nKids) 47 | pBern <- taxes(incomes, c(brackets$bernieIndBrackets, 48 | brackets$bernieEmpBrackets), totalDeduction) %>% 49 | mutate(set = "Bernie") %>% 50 | applyCredits(filingStatus, nKids) 51 | 52 | pDat <- rbind(gather(rbind(pCur, pBern), 53 | expense, amount, -income, -effectiveIncome, -set, -agi)) 54 | 55 | #total effective tax rates 56 | pDatSum <- pDat %>% group_by(set, income, effectiveIncome, agi) %>% 57 | summarize(tTax = sum(amount)) %>% ungroup %>% 58 | mutate(eTax = tTax / effectiveIncome) 59 | 60 | pDatSum <- mutate(pDatSum, percentile = getPercentileForIncome(income)) 61 | 62 | #differences between plans / ribbon data 63 | pDatDiff <- inner_join(filter(pDatSum, set == "Bernie"), 64 | filter(pDatSum, set == "Current"), 65 | by = c("income", "percentile")) %>% 66 | rename(eTaxBern = eTax.x, eTaxCur = eTax.y) %>% 67 | mutate(increase = eTaxBern > eTaxCur, 68 | iTop = ifelse(increase, eTaxBern, NA), 69 | iBottom = ifelse(increase, eTaxCur, NA), 70 | dTop = ifelse(!increase, eTaxCur, NA), 71 | dBottom = ifelse(!increase, eTaxBern, NA)) 72 | 73 | 74 | png("img/png/bernieBillionsWithEmpTax.png", width = 1024, height = 768) 75 | source("R/plots/berniePooledPlot.R", print.eval = T) 76 | dev.off() 77 | -------------------------------------------------------------------------------- /R/plots/berniePlotSingle.R: -------------------------------------------------------------------------------- 1 | savings <- datDiff %>% filter(payer == "Individual") %>% 2 | mutate(delta = (eTaxCur - eTaxBern) * income, 3 | mid = (eTaxCur + eTaxBern)/2) 4 | 5 | whichSavings <- c(which.max(savings$delta), 6 | which.min(abs(savings$percentile - .5)), 7 | which.min(abs(savings$percentile - .75)), 8 | which.max(savings$percentile)) 9 | savings <- savings[whichSavings, 10 | c("income", "delta", "mid", 11 | "eTaxCur", "eTaxBern")] 12 | savings$percentile <- getPercentileForIncome(savings$income) 13 | savings$hjust <- c(.5, .5, .5, -.05) 14 | savings$fill <- ifelse(savings$delta < 0, "Increase", "Savings") 15 | savings$delta <- round(abs(savings$delta)) 16 | savings$lab <- paste0(savings$fill, ": ", scales::dollar(savings$delta)) 17 | #savings$mid[1] <- savings$mid[1] + .015 18 | topBracketSize <- 1 - acs$centile[nrow(acs) - 1] 19 | topBracketSize <- round(topBracketSize, 20 | digits = ifelse(topBracketSize < .01, 3, 2)) 21 | savings$lab[nrow(savings)] <- paste("Top ", 22 | scales::percent(topBracketSize), 23 | " average\nIncome: $", 24 | round(acs$income[nrow(acs)]/1000), 25 | "K\n", savings$lab[nrow(savings)], 26 | sep = "") 27 | 28 | 29 | 30 | shadowOffsetX <- .002 31 | shadowOffsetY <- -.002 32 | shadowSize <- 2.5 33 | shadowColor <- c("grey30", "grey30") 34 | #line colors bernie, current 35 | #trendColors <- c("#287CBF", "#44445c") 36 | trendColors <- c("#2d8cd8", "#48476f") 37 | 38 | 39 | #fill colors savings, increase 40 | #fillColors <- c("#1FC77F", "#FFB450") 41 | fillColors <- c("#21DC91", "#FF9400") 42 | 43 | ggplot(filter(datDiff, payer == "Individual"), aes(x = percentile)) + 44 | geom_ribbon(aes(ymax = iTop, ymin = iBottom, fill = "Increase")) + 45 | geom_ribbon(aes(ymax = dTop, ymin = dBottom, fill = "Savings")) + 46 | geom_segment(aes(xend = percentile, y = eTaxBern, yend = eTaxCur), 47 | data = savings, linetype = 3, color = trendColors[1], 48 | size = 1.25, alpha = .8) + 49 | geom_line(aes(y = eTaxBern + shadowOffsetY , x = percentile + shadowOffsetX), 50 | size = shadowSize, color = shadowColor[1]) + 51 | geom_line(aes(y = eTaxCur + shadowOffsetY, x = percentile + shadowOffsetX), 52 | size = shadowSize, color = shadowColor[2]) + 53 | geom_line(aes(y = eTaxBern, color = "Bernie"), size = 2.75) + 54 | geom_line(aes(y = eTaxCur, color = "Current"), size = 2.75) + 55 | #scale_x_log10(breaks = percentiles$income, labels = percentiles$xlabs) + 56 | scale_x_continuous(breaks = c(.25, .5, .75, .95), 57 | labels = centileLabeler) + 58 | scale_y_continuous(labels = scales::percent) + 59 | scale_color_manual("Tax Plan", values = trendColors) + 60 | scale_fill_manual("Change under Bernie's Plans", 61 | limits = c("Savings", "Increase"), 62 | values = fillColors) + 63 | #guides(color = guide_legend(order = 1)) + 64 | guides(color = F, fill = F) + 65 | theme(axis.line = element_blank(), 66 | legend.position = "bottom", 67 | text = element_text(size = 24), 68 | axis.title.y = element_text(margin = margin(0, 15, 0, 0)), 69 | axis.title.x = element_text(margin = margin(15, 0, 0, 0)), 70 | plot.title = element_text(margin = margin(0, 0, 30, 0), size = 40, 71 | hjust = 0), 72 | panel.grid.major.x = 73 | element_line(colour = "grey80", size = 1, linetype = 2), 74 | panel.background = element_blank(), 75 | axis.ticks.x = element_blank()) + 76 | labs(y = "Tax and Healthcare Burden (% of income)", 77 | x = "Income for a Single Male (USD)", 78 | title = "Just How Much Would Bernie Sanders Tax Me?") + 79 | coord_cartesian(xlim = c(getPercentileForIncome(min(incomes)), 1.15)) + 80 | annotate("text", x = .275, y = .29, 81 | label = "Taxes + Healthcare Expense Now", 82 | angle = 0, hjust = 0, color = trendColors[2], size = 12, 83 | fontface = "bold") + 84 | annotate("text", x = .30, y = .08, 85 | label = "Bernie's Plans for Taxes, Healthcare and More", 86 | angle = 26, hjust = 0, color = trendColors[1], size = 12, 87 | fontface = "bold") + 88 | 89 | geom_label(aes(y = mid, label = lab, hjust = hjust), data = savings, 90 | size = 6, alpha = .95) 91 | -------------------------------------------------------------------------------- /R/plots/berniePlotSingleF.R: -------------------------------------------------------------------------------- 1 | savings <- datDiff %>% filter(payer == "Individual") %>% 2 | mutate(delta = (eTaxCur - eTaxBern) * income, 3 | mid = (eTaxCur + eTaxBern)/2) 4 | 5 | whichSavings <- c(which.max(savings$delta), 6 | which.min(abs(savings$percentile - .5)), 7 | which.min(abs(savings$percentile - .75)), 8 | which.max(savings$percentile)) 9 | savings <- savings[whichSavings, 10 | c("income", "delta", "mid", 11 | "eTaxCur", "eTaxBern")] 12 | savings$percentile <- getPercentileForIncome(savings$income) 13 | savings$hjust <- c(.5, .5, .5, -.05) 14 | savings$fill <- ifelse(savings$delta < 0, "Increase", "Savings") 15 | savings$delta <- round(abs(savings$delta)) 16 | savings$lab <- paste0(savings$fill, ": ", scales::dollar(savings$delta)) 17 | savings$mid[1] <- savings$mid[1] - .015 18 | topBracketSize <- 1 - acs$centile[nrow(acs) - 1] 19 | topBracketSize <- round(topBracketSize, 20 | digits = ifelse(topBracketSize < .01, 3, 2)) 21 | savings$lab[nrow(savings)] <- paste("Top ", 22 | scales::percent(topBracketSize), 23 | " average\nIncome: $", 24 | round(acs$income[nrow(acs)]/1000), 25 | "K\n", savings$lab[nrow(savings)], 26 | sep = "") 27 | 28 | 29 | 30 | shadowOffsetX <- .002 31 | shadowOffsetY <- -.002 32 | shadowSize <- 2.5 33 | shadowColor <- c("grey30", "grey30") 34 | #line colors bernie, current 35 | #trendColors <- c("#287CBF", "#44445c") 36 | trendColors <- c("#2d8cd8", "#48476f") 37 | 38 | 39 | #fill colors savings, increase 40 | #fillColors <- c("#1FC77F", "#FFB450") 41 | fillColors <- c("#21DC91", "#FF9400") 42 | 43 | ggplot(filter(datDiff, payer == "Individual"), aes(x = percentile)) + 44 | geom_ribbon(aes(ymax = iTop, ymin = iBottom, fill = "Increase")) + 45 | geom_ribbon(aes(ymax = dTop, ymin = dBottom, fill = "Savings")) + 46 | geom_segment(aes(xend = percentile, y = eTaxBern, yend = eTaxCur), 47 | data = savings, linetype = 3, color = trendColors[1], 48 | size = 1.25, alpha = .8) + 49 | geom_line(aes(y = eTaxBern + shadowOffsetY , x = percentile + shadowOffsetX), 50 | size = shadowSize, color = shadowColor[1]) + 51 | geom_line(aes(y = eTaxCur + shadowOffsetY, x = percentile + shadowOffsetX), 52 | size = shadowSize, color = shadowColor[2]) + 53 | geom_line(aes(y = eTaxBern, color = "Bernie"), size = 2.75) + 54 | geom_line(aes(y = eTaxCur, color = "Current"), size = 2.75) + 55 | #scale_x_log10(breaks = percentiles$income, labels = percentiles$xlabs) + 56 | scale_x_continuous(breaks = c(.25, .5, .75, .95), 57 | labels = centileLabeler) + 58 | scale_y_continuous(labels = scales::percent) + 59 | scale_color_manual("Tax Plan", values = trendColors) + 60 | scale_fill_manual("Change under Bernie's Plans", 61 | limits = c("Savings", "Increase"), 62 | values = fillColors) + 63 | #guides(color = guide_legend(order = 1)) + 64 | guides(color = F, fill = F) + 65 | theme(axis.line = element_blank(), 66 | legend.position = "bottom", 67 | text = element_text(size = 24), 68 | axis.title.y = element_text(margin = margin(0, 15, 0, 0)), 69 | axis.title.x = element_text(margin = margin(15, 0, 0, 0)), 70 | plot.title = element_text(margin = margin(0, 0, 30, 0), size = 40, 71 | hjust = 0), 72 | panel.grid.major.x = 73 | element_line(colour = "grey80", size = 1, linetype = 2), 74 | panel.background = element_blank(), 75 | axis.ticks.x = element_blank()) + 76 | labs(y = "Tax and Healthcare Burden (% of income)", 77 | x = "Income for a Single Female (USD)", 78 | title = "Just How Much Would Bernie Sanders Tax Me?") + 79 | coord_cartesian(xlim = c(getPercentileForIncome(min(incomes)), 1.15)) + 80 | annotate("text", x = .275, y = .26, 81 | label = "Taxes + Healthcare Expense Now", 82 | angle = 0, hjust = 0, color = trendColors[2], size = 12, 83 | fontface = "bold") + 84 | annotate("text", x = .38, y = 0.045, 85 | label = "Bernie's Plans for Taxes, Healthcare and More", 86 | angle = 26, hjust = 0, color = trendColors[1], size = 12, 87 | fontface = "bold") + 88 | 89 | geom_label(aes(y = mid, label = lab, hjust = hjust), data = savings, 90 | size = 6, alpha = .95) 91 | -------------------------------------------------------------------------------- /R/plots/berniePlot.R: -------------------------------------------------------------------------------- 1 | savings <- datDiff %>% filter(payer == "Individual") %>% 2 | mutate(delta = (eTaxCur - eTaxBern) * income, 3 | mid = (eTaxCur + eTaxBern)/2) 4 | 5 | whichSavings <- c(which.min(abs(savings$percentile - .25)), 6 | which.min(abs(savings$percentile - .5)), 7 | which.min(abs(savings$percentile - .75)), 8 | which.max(savings$percentile)) 9 | #whichSavings <- c(40000, 80000, 120000, 400000) 10 | savings <- savings[whichSavings, 11 | c("income", "delta", "mid", 12 | "eTaxCur", "eTaxBern")] 13 | #savings$percentile <- getPercentileForIncome(whichSavings) 14 | savings$percentile <- c(.25, .5, .75, max(datDiff$percentile)) 15 | savings$hjust <- c(.5, .5, .5, -.05) 16 | savings$fill <- ifelse(savings$delta < 0, "Increase", "Savings") 17 | savings$delta <- round(abs(savings$delta)) 18 | savings$lab <- paste0(savings$fill, ": ", scales::dollar(savings$delta)) 19 | #savings$mid[1] <- savings$mid[1] + .05 20 | topBracketSize <- 1 - acs$centile[nrow(acs) - 1] 21 | topBracketSize <- round(topBracketSize, 22 | digits = ifelse(topBracketSize < .01, 3, 2)) 23 | savings$lab[nrow(savings)] <- paste("Top ", 24 | scales::percent(topBracketSize), 25 | " average\nIncome: $", 26 | round(acs$income[nrow(acs)]/1000), 27 | "K\n", savings$lab[nrow(savings)], 28 | sep = "") 29 | 30 | 31 | 32 | shadowOffsetX <- .002 33 | shadowOffsetY <- -.002 34 | shadowSize <- 2.5 35 | shadowColor <- c("grey30", "grey30") 36 | #line colors bernie, current 37 | #trendColors <- c("#287CBF", "#44445c") 38 | trendColors <- c("#2d8cd8", "#48476f") 39 | 40 | 41 | #fill colors savings, increase 42 | #fillColors <- c("#1FC77F", "#FFB450") 43 | fillColors <- c("#21DC91", "#FF9400") 44 | 45 | ggplot(filter(datDiff, payer == "Individual"), aes(x = percentile)) + 46 | geom_ribbon(aes(ymax = iTop, ymin = iBottom, fill = "Increase")) + 47 | geom_ribbon(aes(ymax = dTop, ymin = dBottom, fill = "Savings")) + 48 | geom_segment(aes(xend = percentile, y = eTaxBern, yend = eTaxCur), 49 | data = savings, linetype = 3, color = trendColors[1], 50 | size = 1.25, alpha = .8) + 51 | geom_line(aes(y = eTaxBern + shadowOffsetY , x = percentile + shadowOffsetX), 52 | size = shadowSize, color = shadowColor[1]) + 53 | geom_line(aes(y = eTaxCur + shadowOffsetY, x = percentile + shadowOffsetX), 54 | size = shadowSize, color = shadowColor[2]) + 55 | geom_line(aes(y = eTaxBern, color = "Bernie"), size = 2.75) + 56 | geom_line(aes(y = eTaxCur, color = "Current"), size = 2.75) + 57 | #scale_x_log10(breaks = percentiles$income, labels = percentiles$xlabs) + 58 | scale_x_continuous(breaks = c(.05, .25, .5, .75, .95), 59 | labels = centileLabeler) + 60 | scale_y_continuous(labels = scales::percent) + 61 | scale_color_manual("Tax Plan", values = trendColors) + 62 | scale_fill_manual("Change under Bernie's Plans", 63 | limits = c("Savings", "Increase"), 64 | values = fillColors) + 65 | #guides(color = guide_legend(order = 1)) + 66 | guides(color = F, fill = F) + 67 | theme(axis.line = element_blank(), 68 | legend.position = "bottom", 69 | text = element_text(size = 24), 70 | axis.title.y = element_text(margin = margin(0, 15, 0, 0)), 71 | axis.title.x = element_text(margin = margin(15, 0, 0, 0)), 72 | plot.title = element_text(margin = margin(0, 0, 30, 0), size = 40), 73 | panel.grid.major.x = 74 | element_line(colour = "grey80", size = 1, linetype = 2), 75 | panel.background = element_blank(), 76 | axis.ticks.x = element_blank()) + 77 | labs(y = "Tax and Healthcare Burden (% of income)", 78 | x = "Income for a Family of 4 (USD)", 79 | title = "Just How Much Would Bernie Sanders Tax Me?") + 80 | coord_cartesian(xlim = c(0, 1.15)) + 81 | annotate("text", x = .21, y = .33, 82 | label = "Taxes + Healthcare Expense Now", 83 | angle = 0, hjust = 0, color = trendColors[2], size = 12, 84 | fontface = "bold") + 85 | annotate("text", x = .23, y = -.195, 86 | label = "Bernie's Plans for Taxes, Healthcare and More", 87 | angle = 28, hjust = 0, color = trendColors[1], size = 12, 88 | fontface = "bold") + 89 | 90 | geom_label(aes(y = mid, label = lab, hjust = hjust), data = savings, 91 | size = 6) 92 | -------------------------------------------------------------------------------- /R/scripts/voxPlots.R: -------------------------------------------------------------------------------- 1 | # Finds marginal rate and ignores "extra" & "deduct" 2 | # Adjusts rates to find true tax rates based on effective income after 3 | # accounting for employer paid compensation that is in addition to income 4 | # These figures are flawed and used for example purposes in an article 5 | getMarginalRateVox <- function(bracketsList, income) { 6 | bracketsList <- bracketsList[!grepl("Healthcare", names(bracketsList))] 7 | rates <- sapply(bracketsList, function(brackets){ 8 | brackets$rate[which(brackets$bottom < income & brackets$cap >= income)] 9 | }) 10 | sum(rates / (1 + sum(rates[grepl("Employer",names(rates))]))) 11 | } 12 | 13 | ##### 14 | # Real tax rate explanation 15 | 16 | 17 | library(ggplot2); library(dplyr) 18 | 19 | inc <- 10000 20 | inc.rate <- .1 21 | prl.rate <- .1 22 | 23 | labFunc <- function(x) { 24 | ef.inc <- inc + inc * prl.rate 25 | scales::percent(1 - (x / ef.inc)) 26 | } 27 | png("img/png/realrates_raw.png", w = 800, h = 200) 28 | data.frame(rate = c(c(1 - inc.rate, inc.rate, prl.rate)), 29 | cat = factor(1:3, labels = c("Take-Home Pay", "Income Tax", 30 | "Payroll Tax")), 31 | lab.x = c(1, 1.23, .78)) %>% 32 | mutate(amount = rate * inc, 33 | lbl = paste(cat, "\n", "Amount:", 34 | scales::dollar(amount), 35 | "\nPortion of Income:", 36 | scales::percent(rate)), 37 | lbl.pos = cumsum(amount) - amount / 2) %>% 38 | ggplot(aes(x = 1, y = amount, fill = cat)) + 39 | geom_bar(stat = "identity") + 40 | geom_text(aes(y = lbl.pos, label = lbl, x = lab.x), 41 | fontface = "bold", size = 4) + 42 | coord_flip() + 43 | scale_y_continuous(breaks = seq(0, 11000, by = 1000), 44 | labels = labFunc) + 45 | scale_fill_brewer(palette = "BuGn", direction = -1) + 46 | labs(x = "", y = "Real Tax Rate") + 47 | theme_classic() + 48 | theme(text = element_text(size = 18), 49 | legend.position = "none", axis.text.y = element_blank(), 50 | axis.line = element_blank(), axis.ticks.y = element_blank(), 51 | plot.margin = grid::unit(c(4,0,0,0), "lines")) 52 | dev.off() 53 | 54 | 55 | ##### 56 | # Math error table 57 | 58 | library(xtable); library(scales) 59 | voxIncomes <- c(0, 18550, 75300, 118500, 151900, 231450, 60 | 250000, 413350, 466950, 500000, 2000000, 61 | 10000000) 62 | bracketsList <- getBrackets() 63 | cur <- sapply(voxIncomes + 1, getMarginalRateVox, 64 | bracketsList = c(bracketsList$currentIndBrackets, 65 | bracketsList$currentEmpBrackets)) 66 | bern <- sapply(voxIncomes + 1, getMarginalRateVox, 67 | bracketsList = c(bracketsList$bernieIndBrackets, 68 | bracketsList$bernieEmpBrackets)) 69 | voxTable <- data.frame(income = voxIncomes, 70 | set = c(rep("Current", length(cur)), 71 | rep("Bernie", length(bern))), 72 | margRate = c(cur, bern), 73 | voxRate = c(.253, .303, .403, .279, .309, .359, .368, 74 | .388, .434, .434, .434, .434, 75 | .341, .391, .491, .367, .397, .447, .620, 76 | .620, .620, .68, .73, .77)) %>% 77 | mutate(voxError = voxRate - margRate) %>% 78 | arrange(income, desc(set)) %>% 79 | mutate_each(funs(percent), margRate, voxRate, voxError) %>% 80 | mutate(income = dollar(income)) 81 | voxTable$income[seq(2, nrow(voxTable), by = 2)] <- "" 82 | names(voxTable) <- c("Taxable Income Above", "Tax Plan", "Real Marginal Rate", 83 | "Matthews's Rate", "Size of Error") 84 | 85 | 86 | tab <- xtable(voxTable) 87 | print(tab, file = "voxTable.txt", type = "html", include.rownames = F) 88 | 89 | 90 | ######### 91 | # Top Marginal Plot 92 | 93 | library(dplyr); library(tidyr); library(ggplot2); library(readxl) 94 | source("R/functions/bernieTaxBrackets.R") 95 | source("R/functions/bernietaxFunctions.R") 96 | 97 | nKids <- 0 98 | filingStatus <- "Married/Joint" 99 | sex <- "M" 100 | 101 | incomes <- 10^seq(4.6, 10, by = .05) 102 | 103 | dat <- taxesByIncomes(incomes, filingStatus, nKids, sex, employer = "pool") 104 | 105 | #total effective tax rates 106 | datSum <- dat %>% group_by(set, income, effectiveIncome, agi) %>% 107 | summarize(tTax = sum(amount)) %>% ungroup %>% 108 | mutate(eTax = tTax / effectiveIncome) 109 | 110 | 111 | trendColors <- c("#2d8cd8", "#48476f") 112 | 113 | crossover <- inner_join(filter(datSum, set == "Bernie"), 114 | filter(datSum, set == "Current"), 115 | by = "income") %>% 116 | mutate(adiff = abs(eTax.x - eTax.y)) %>% 117 | arrange(adiff) %>% 118 | filter(row_number() ==1) %>% 119 | magrittr::extract2("eTax.y") 120 | 121 | ybrks <- c(min(datSum$eTax), max(datSum$eTax), 122 | max(filter(datSum, set == "Current", income > 2500000)$eTax), 123 | max(filter(datSum, income < 250000)$eTax), crossover, .77) 124 | 125 | png("img/png/topmarginal_raw.png", w = 800, h = 400) 126 | ggplot(datSum, aes(x = income, y = eTax, color = set)) + 127 | geom_line(size = 2.75) + 128 | scale_x_log10(breaks = c(50000, 250000, 10^(6:10)), 129 | labels = scales::dollar) + 130 | scale_y_continuous(labels = scales::percent, breaks = ybrks) + 131 | scale_color_manual("Tax Plan", values = trendColors) + 132 | coord_cartesian(ylim = ybrks[c(1, length(ybrks))]) + 133 | theme(axis.line = element_blank(), 134 | legend.position = "none", 135 | text = element_text(size = 18), 136 | axis.title.y = element_text(margin = margin(0, 15, 0, 0)), 137 | axis.title.x = element_text(margin = margin(15, 0, 0, 0)), 138 | panel.grid.major.x = element_blank(), 139 | panel.grid.major.y = 140 | element_line(colour = "grey80", size = 1, linetype = 2), 141 | panel.background = element_blank(), 142 | axis.ticks.y = element_blank(), 143 | plot.margin = grid::unit(c(2, 2, 0.1, 0.1), "lines")) + 144 | labs(y = "Effective Rate", 145 | x = "Income") 146 | dev.off() 147 | -------------------------------------------------------------------------------- /R/plots/barStylePlot.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | library(dplyr); library(tidyr); library(ggplot2); library(readxl) 4 | source("R/functions/bernieTaxBrackets.R") 5 | source("R/functions/bernietaxFunctions.R") 6 | 7 | barStylePlot <- function(filingStatus, nKids, sex, 8 | employer = c("ignore", "isolate", "split", "pool"), 9 | customIncomes = numeric(0), 10 | labelPercents = T) { 11 | employer = match.arg(employer) 12 | 13 | acsList <- getCensusIncomes(filingStatus, sex) 14 | 15 | #get wide range of incomes to find a few landmark incomes to display 16 | incomeRange <- c(seq(min(acsList$acs$income), 17 | max(acsList$acs$income), by = 1000), 18 | max(acsList$acs$income)) 19 | dat <- taxesByIncomes(incomeRange, filingStatus, nKids, sex, employer) 20 | savings <- netTaxDifferences(dat, acsList) 21 | 22 | # find breakeven point as income level with smallest savings that is greater 23 | # than the lowest income level with savings 24 | savings <- arrange(savings, income) 25 | startIncome <- savings$income[min(which(savings$delta > 0))] 26 | savings <- filter(savings, income > startIncome) 27 | breakeven <- savings$income[which.max(ifelse(savings$delta > 0, NA, 28 | savings$delta))] 29 | maxSavings <- savings$income[which.max(savings$delta)] 30 | 31 | #choose breakeven point, common percentiles, max savings, highest group, and 32 | #any custom incomes as incomes to display 33 | incomes <- c(min(acsList$acs$income), maxSavings, 34 | max(acsList$acs$income), customIncomes) 35 | if(employer != "split") incomes <- c(incomes, breakeven) 36 | #avoid ploting two nearby incomes with landmark incomes are near common 37 | #percentiles 38 | commonPercentiles <- unlist(sapply(c(.25, .5, .75, .95), function(x) { 39 | x[!any(abs(x - na.omit(acsList$getPercentileForIncome(incomes))) < .04)] 40 | })) 41 | commonPercentiles <- acsList$getIncomeForPercentile(c(.05, commonPercentiles)) 42 | incomes <- sort(unique(c(incomes, commonPercentiles))) 43 | 44 | incomeScaleFun <- approxfun(incomes, seq_along(incomes)) 45 | denseDistr <- rep(acsList$acs$income, acsList$acs$Number) 46 | denseFun <- MASS::fitdistr(na.omit(incomeScaleFun(denseDistr)), "lognormal") 47 | callDenseFun <- function(x) { 48 | dlnorm(x, meanlog = denseFun$estimate["meanlog"], 49 | sdlog = denseFun$estimate["sdlog"]) 50 | } 51 | 52 | dat <- taxesByIncomes(incomes, filingStatus, nKids, sex, employer) 53 | dat$payer = factor(dat$payer) 54 | levels(dat$payer) <- list("Personal Taxes" = "Individual", 55 | "Employer-Paid Taxes" = "Employer") 56 | 57 | dat2 <- filter(dat, amount != 0) %>% 58 | mutate(percentile = acsList$getPercentileForIncome(income), 59 | set = factor(set, levels = c("Current", "Bernie")), 60 | incomeFactor = factor(income, levels = incomes), 61 | offset = (as.numeric(set) - (length(levels(set)) + 1) / 2) / 62 | (length(levels(set)) + .6) + as.numeric(incomeFactor), 63 | expenseGroup = factor(expense)) 64 | 65 | levels(dat2$expenseGroup) <- list("Income Tax" = c("Income Tax"), 66 | "Payroll Taxes" = 67 | c("Social Security Tax", 68 | "Medicare Tax", 69 | "Family Leave Tax", 70 | "Employer Payroll Tax"), 71 | "Healthcare Tax" = 72 | c("Medicare-for-all Tax", 73 | "Employer Medicare-for-all Tax"), 74 | "Healthcare Premiums" = 75 | c("Healthcare Premiums", 76 | "Employer Healthcare\nContribution"), 77 | "Healthcare Out-of-Pocket" = 78 | c("Healthcare Expenses")) 79 | dat2 <- group_by(dat2, offset, income, incomeFactor, effectiveIncome, set, 80 | payer, expenseGroup) %>% 81 | summarise(amount = sum(amount)) %>% 82 | group_by(payer, set, income) %>% 83 | # effective income is only a useful concept when pooling employer/employee 84 | mutate(eTax = amount / ifelse(employer == "pool", 85 | effectiveIncome, income), 86 | # small numbers on the ends can be pushed outside of the bar for 87 | # better display 88 | labelyPos = ifelse(abs(eTax) < .017 & 89 | grepl("Income Tax", expenseGroup), 90 | "Left", 91 | ifelse(abs(eTax) < .017 & 92 | grepl("Healthcare O", expenseGroup), 93 | "Right", "Middle")), 94 | labely = ifelse(labelyPos == "Left", 0, 95 | ifelse(labelyPos == "Right", cumsum(eTax), 96 | cumsum(eTax) - 0.5 * eTax)), 97 | pctLabelJust = ifelse(labelyPos == "Middle", NA, .5) + 98 | .6 * (labelyPos == "Left") + 99 | -.5 * (labelyPos == "Right"), 100 | # hide text for very small amounts for cleaner display (unless they 101 | # are already pushed out). Also hide negative rates and rates that 102 | # would display left of 0 103 | pctLabelText = ifelse((eTax >= .0035 | labelyPos != "Middle") & 104 | labely >= 0 & eTax > 0, 105 | scales::percent(round(eTax, 3)), ""), 106 | pctLabelCol = ifelse(labelyPos == "Right" & 107 | labely < callDenseFun(offset), 108 | "white", "black")) 109 | 110 | centileLabeler <- function(x) { 111 | inc <- incomes[as.numeric(x)] 112 | pct <- acsList$getPercentileForIncome(inc) 113 | lab <- ifelse(is.na(pct), scales::dollar(inc), 114 | acsList$centileLabeler(pct)) 115 | paste0(lab, ifelse(inc == maxSavings, "\n(Maximum Savings)", 116 | ifelse(inc == breakeven, 117 | "\n(Cross-over Point)",""))) 118 | } 119 | 120 | #Create a parellel ramp palettes in two colors for bar groups 121 | cols <- dat2 %>% ungroup %>% select(exp = expenseGroup, set) %>% unique 122 | cols <- arrange(cols, set, exp) 123 | cols$key <- paste(cols$set, cols$exp) 124 | blues <- colorRampPalette(c("dodgerblue4", "slategray2")) 125 | greys <- colorRampPalette(c("grey40", "grey80")) 126 | fillPal <- c(greys(nrow(filter(cols, set == "Current"))), 127 | blues(nrow(filter(cols, set == "Bernie")))) 128 | names(fillPal) <- cols$key 129 | 130 | #find labels for lightest color of each palette for the label fill 131 | lastBernColLab <- names(fillPal)[max(grep("Bernie", names(fillPal)))] 132 | lastCurColLab <- names(fillPal)[max(grep("Current", names(fillPal)))] 133 | savings <- netTaxDifferences(dat, acsList) 134 | savings <- savings %>% 135 | mutate(labely = pmax(pmin(eTaxBern, eTaxCur), 0), 136 | set = ifelse(increase, "Current", "Bernie"), 137 | hjust = -.3, 138 | fillKey = ifelse(increase, lastCurColLab, lastBernColLab)) 139 | #Need correspnding x-axis offset positions to display savings labels in 140 | #correct place 141 | savings <- dat2 %>% 142 | ungroup() %>% 143 | select(income, set, offset) %>% 144 | unique %>% 145 | inner_join(savings) 146 | 147 | # xlims <- c(min(dat2[dat2$income == startIncome, "offset"]), 148 | # max(dat2$offset) + .2) 149 | # #expand upper y limit for increase/decrease labels 150 | # ylims <- c(0, 1.2 * max( 151 | # (dat2 %>% group_by(set, income) %>% summarise(eTax = sum(eTax)))$eTax)) 152 | 153 | title <- paste("Bernie Sanders Tax Plan Impact for", 154 | ifelse(filingStatus == "Married/Joint", 155 | paste("Family of", nKids + 2), 156 | paste("Single", ifelse(sex == "M", "Male", "Female"), 157 | ifelse(nKids > 0, paste0("with ", nKids, " Child", 158 | ifelse(nKids > 1, "ren", 159 | "")),"")))) 160 | 161 | plt <- ggplot(dat2, aes(x = offset, y = eTax, 162 | fill = paste(set, expenseGroup))) + 163 | stat_function(fun = dlnorm, args = denseFun$estimate, 164 | geom = "area", fill = "black", alpha = .75) + 165 | geom_bar(position = "stack", stat = "identity", 166 | data = filter(dat2, set == "Bernie"), width = 0.35) + 167 | geom_bar(position = "stack", stat = "identity", 168 | data = filter(dat2, set == "Current"), width = 0.35) + 169 | geom_label(aes(y = labely, label = lab, hjust = hjust, fill = fillKey), 170 | data = savings, size = 4.5) + 171 | scale_fill_manual("Expense", values = fillPal) + 172 | scale_color_manual(guide = F, values = c("black", "white")) + 173 | scale_x_reverse(breaks = seq_along(incomes), labels = centileLabeler) + 174 | scale_y_continuous(labels = scales::percent, breaks = seq(0, 1, by = .1)) + 175 | #coord_flip(xlim = xlims, ylim = ylims) + 176 | coord_flip() + 177 | labs(x = "Income", y = "Effective Tax Rate with Healthcare Burden", 178 | title = title) + 179 | theme(legend.position = "bottom", text = element_text(size = 18)) 180 | if(employer == "split") plt <- plt + facet_grid(~payer) 181 | if(labelPercents) plt <- plt + 182 | geom_text(aes(y = labely, label = pctLabelText, hjust = pctLabelJust, 183 | color = pctLabelCol), fontface = "bold") 184 | plt 185 | } 186 | -------------------------------------------------------------------------------- /R/functions/bernietaxFunctions.R: -------------------------------------------------------------------------------- 1 | ##Utility/workshorse functions 2 | #Calculate tax owed in a marginal tax system (different rates apply to portions 3 | #of income in different brackets) for a vector of incomes 4 | tax <- function(brackets, income, deduction) { 5 | rowSums(do.call(mapply, c(FUN = function(bottom, cap, rate, extra, deduct){ 6 | income <- income - deduction * deduct 7 | margin <- pmin(income, cap) - bottom 8 | ifelse(margin <= 0, 0, margin * rate + extra) 9 | }, brackets))) 10 | } 11 | 12 | #Apply tax function for multiple taxes to a vector of incomes 13 | taxes <- function(incomes, bracketsList, deductions = 0, 14 | deductHealthCarePremiums = F) { 15 | names(incomes) <- as.character(incomes) 16 | ret <- sapply(bracketsList, tax, income = incomes, deduction = deductions) 17 | ret <- data.frame(ret, check.names = F) 18 | if(deductHealthCarePremiums && !is.null(ret[["Healthcare Premiums"]])) { 19 | ret <- sapply(bracketsList, tax, income = incomes, 20 | deduction = deductions + ret[["Healthcare Premiums"]]) 21 | ret <- data.frame(ret, check.names = F) 22 | } 23 | ret$income <- incomes 24 | ret$effectiveIncome <- incomes + 25 | rowSums(ret[, na.omit(match(taxNamesEmp, names(ret)))], na.rm = T) 26 | ret$agi <- pmax(incomes - deductions, 0) 27 | ret 28 | } 29 | 30 | #Apply earned income tax credit and child tax credit to results of taxes 31 | #function. CTC must be calculated after EITC using the modified income tax 32 | applyCredits <- function(calculatedTaxes, filingStatus, nKids) { 33 | mutate(calculatedTaxes, 34 | `Income Tax` = `Income Tax` - eitc(income, agi, filingStatus, nKids), 35 | `Income Tax` = `Income Tax` - 36 | ctc(agi, income, `Income Tax`, filingStatus, nKids)) 37 | } 38 | 39 | # Read census income file for filer type and compute percentiles 40 | # income distribution data from US census, 2014 family incomes 41 | # https://www.census.gov/hhes/www/cpstables/032015/faminc/toc.htm 42 | # https://www.census.gov/hhes/www/cpstables/032015/perinc/pinc11_000.htm 43 | getCensusIncomes <- function(filingStatus, sex) { 44 | if(filingStatus == "Married/Joint") { 45 | f <- "data/finc07.xls" 46 | } else if(sex == "M") { 47 | f <- "data/pinc11_1.xls" 48 | } else { 49 | f <- "data/pinc11_2.xls" 50 | 51 | } 52 | t <- read_excel(f, skip = 8)[c(-1, -46), 1:3] %>% 53 | mutate(prop = Number / sum(Number), centile = cumsum(prop), 54 | payer = "Population") 55 | names(t)[3] <- "income" 56 | tops <- gsub(",", "", t[[1]]) 57 | tops <- as.numeric(regmatches(tops, regexpr("[[:digit:]]+$", tops))) 58 | t$income <- c(tops, t$income[nrow(t)]) 59 | t 60 | getIncomeForPercentile <- approxfun(t$centile, t$income) 61 | getPercentileForIncome <- approxfun(t$income, t$centile) 62 | # glm modeling allows for smoother interpolation, but becomes inaccurate 63 | # at extremes. Linear interpolation used instead 64 | # mod <- glm(centile ~ income, acs, family = "binomial") 65 | # getPercentileForIncome <- function(x) { 66 | # predict(mod, data.frame(income = x), type = "response") 67 | # } 68 | 69 | centileLabeler <- function(breaks) { 70 | #browser() 71 | incs <- scales::dollar(round(getIncomeForPercentile(breaks))) 72 | topBracket <- which(breaks == 1) 73 | if(length(topBracket)) { 74 | breaks[topBracket] <- 1 - t$centile[nrow(t) - 1] 75 | breaks[topBracket] <- round(breaks[topBracket], 76 | digits = ifelse(breaks[topBracket] < .01, 3, 2)) 77 | } 78 | #pmin used to avoid rounding up to "100th percentile" 79 | pct <- pmin(round(breaks * 100), 99) 80 | hundos <- which(pct == 99) 81 | lastDig <- substring(as.character(pct), 82 | nchar(as.character(pct)), 83 | nchar(as.character(pct))) 84 | getSuffix <- function(x) { 85 | substring(as.character(x), nchar(as.character(x)), 86 | nchar(as.character(x))) %>% 87 | switch("1" = "st", "2" = "nd", "3" = "rd", "th") 88 | } 89 | pct <- paste0(pct, sapply(pct, getSuffix), " Percentile") 90 | pct[breaks == .5] <- "Median" 91 | pct[topBracket] <- paste0("Top ", breaks[topBracket] * 100, "% Average") 92 | pct[hundos] <- paste0(">", pct[hundos]) 93 | paste(incs, pct, sep = "\n") 94 | } 95 | list(acs = t, getIncomeForPercentile = getIncomeForPercentile, 96 | getPercentileForIncome = getPercentileForIncome, 97 | centileLabeler = centileLabeler) 98 | } 99 | 100 | ##Functions to implement tax laws 101 | 102 | ##Deduction and exemptions 103 | #https://www.irs.com/articles/2015-federal-tax-rates-personal-exemptions-and-standard-deductions 104 | #https://www.irs.gov/publications/p17/ch03.html 105 | getDeduction <- function(incomes, 106 | filingStatus = c("Married/Joint", "Married/Separate", 107 | "Head of Household", "Single"), 108 | nKids, usePhaseOut = T) { 109 | filingStatus <- match.arg(filingStatus) 110 | # https://www.irs.com/articles/2015-federal-tax-rates-personal-exemptions-and-standard-deductions 111 | standardDeduction <- switch(filingStatus, 112 | "Married/Joint" = 12600, 113 | "Married/Separate" = 6300, 114 | "Head of Household" = 9250, 115 | "Single" = 6300) 116 | # https://www.irs.gov/publications/p17/ch03.html 117 | exemptions <- (ifelse(filingStatus == "Married/Joint", 2, 1) + nKids) * 4000 118 | exPhaseOutStart <- switch(filingStatus, 119 | "Married/Joint" = 309900, 120 | "Married/Separate" = 154950, 121 | "Head of Household" = 284050, 122 | "Single" = 258250) 123 | exPhaseOut <- 124 | pmin(ceiling(pmax(0, incomes - exPhaseOutStart) / 2500) * .02, 1) 125 | standardDeduction + exemptions * (1 - exPhaseOut * usePhaseOut) 126 | 127 | } 128 | 129 | ##Earned income tax credit 130 | #https://www.irs.gov/Credits-&-Deductions/Individuals/Earned-Income-Tax-Credit/EITC-Income-Limits-Maximum-Credit-Amounts 131 | #https://www.law.cornell.edu/uscode/text/26/32 132 | eitc <- function(inc, agi, 133 | filingStatus = c("Married/Joint", "Married/Separate", 134 | "Head of Household", "Single"), 135 | nKids) { 136 | filingStatus <- match.arg(filingStatus) 137 | kidSwitch <- pmin(nKids, 3) + 1 138 | max <- switch(kidSwitch, 503, 3359, 5548, 6242) 139 | if(filingStatus == "Married/Joint") { 140 | fullPhaseout <- switch(kidSwitch, 20330, 44651, 49974, 53267) 141 | } else { 142 | fullPhaseout <- switch(kidSwitch, 14820, 39131, 44454, 47747) 143 | } 144 | #fullPhaseout <- 44651 145 | pPhaseout <- .2106 146 | pPhasein <- .4 147 | #calulcate phaseout threshold based on where credit reduces to $0 148 | startPhaseout <- fullPhaseout - max / pPhaseout 149 | # credit = 40% of income up to max minus 21.05% percent of agi over phaseout 150 | # threshold down to a minimum credit of $0 151 | pmin(inc * pPhasein, max) - 152 | pmin(pmax(agi - startPhaseout, 0) * pPhaseout, max) 153 | } 154 | 155 | ##Child tax credit 156 | #https://www.irs.gov/publications/p972/ar02.html 157 | #https://www.irs.gov/pub/irs-pdf/f1040s8.pdf 158 | ctc <- function(agi, income, incTax, 159 | filingStatus = c("Married/Joint", "Married/Separate", 160 | "Head of Household", "Single"), 161 | nkids) { 162 | filingStatus <- match.arg(filingStatus) 163 | incTax <- pmax(0, incTax) 164 | ctc <- nkids * 1000 165 | phaseOut <- switch(filingStatus, 166 | "Married/Joint" = 110000, 167 | "Married/Separate" = 55000, 168 | "Head of Household" = 75000, 169 | "Single" = 75000) 170 | #reduce max ctc by 5% of agi over phaseout threshold rounded up to nearest 171 | #thousand 172 | ctc <- pmax(ctc - pmax(ceiling((agi - phaseOut) / 1000) * 1000 * .05, 0), 0) 173 | #creditable ctc is smaller of remaning ctc (after taxes reduced to 0) or 15% 174 | #of earned income over $3K 175 | actc <- pmax(pmin(ctc - incTax, .15 * pmax(income - 3000, 0)), 0) 176 | #credit is full ctc up to the point that taxes are reduced to zero, plus 177 | #credtiable portion of the remainder 178 | pmin(ctc, incTax) + actc 179 | } 180 | 181 | 182 | taxesByIncomes <- function(incomes, filingStatus, nKids, sex, 183 | employer = c("ignore", "split", "isolate", "pool"), 184 | useCorporateWelfare = F) { 185 | employer = match.arg(employer) 186 | totalDeductionCur <- getDeduction(incomes, filingStatus, nKids) 187 | totalDeductionBern <- getDeduction(incomes, filingStatus, nKids, 188 | usePhaseOut = F) 189 | 190 | brackets <- getBrackets(filingStatus, useCorporateWelfare, nKids) 191 | cb <- brackets$currentIndBracket 192 | bb <- brackets$bernieIndBrackets 193 | if(employer == "pool") { 194 | cb <- c(cb, brackets$currentEmpBrackets) 195 | bb <- c(bb, brackets$bernieEmpBrackets) 196 | } 197 | cur <- taxes(incomes, cb, totalDeductionCur, deductHealthCarePremiums = T) %>% 198 | mutate(set = "Current", payer = "Individual") %>% 199 | applyCredits(filingStatus, nKids) 200 | bern <- taxes(incomes, bb, totalDeductionBern) %>% 201 | mutate(set = "Bernie", payer = "Individual") %>% 202 | applyCredits(filingStatus, nKids) 203 | 204 | dat <- gather(rbind(cur, bern), expense, amount, 205 | -income, -effectiveIncome, -set, -payer, -agi) 206 | if(employer %in% c("split", "isolate")) { 207 | curEmp <- taxes(incomes, brackets$currentEmpBrackets) %>% 208 | mutate(set = "Current", payer = "Employer") 209 | bernEmp <- taxes(incomes, brackets$bernieEmpBrackets) %>% 210 | mutate(set = "Bernie", payer = "Employer") 211 | emps <- gather(rbind(curEmp, bernEmp), expense, amount, -income, 212 | -effectiveIncome, -set, -payer, -agi) 213 | } 214 | switch(employer, 215 | "split" = rbind(dat, emps), 216 | "isolate" = emps, 217 | dat) 218 | } 219 | 220 | netTaxDifferences <- function(dat, acsList) { 221 | #total effective tax rates 222 | datSum <- dat %>% group_by(payer, set, income, effectiveIncome, agi) %>% 223 | summarize(tTax = sum(amount)) %>% ungroup %>% 224 | mutate(eTax = tTax / effectiveIncome, 225 | percentile = acsList$getPercentileForIncome(income)) 226 | 227 | #differences between plans / savings data 228 | inner_join(filter(datSum, set == "Bernie"), 229 | filter(datSum, set == "Current"), 230 | by = c("payer", "income", "percentile")) %>% 231 | rename(eTaxBern = eTax.x, eTaxCur = eTax.y, 232 | tTaxBern = tTax.x, tTaxCur = tTax.y) %>% 233 | mutate(increase = eTaxBern > eTaxCur, delta = tTaxCur - tTaxBern, 234 | lab = paste0(ifelse(increase, "Increase: ", "Savings: "), 235 | scales::dollar(abs(round(delta))))) 236 | 237 | } 238 | 239 | -------------------------------------------------------------------------------- /R/functions/bernieTaxBrackets.R: -------------------------------------------------------------------------------- 1 | taxNamesInd <- c("Income Tax", "Social Security Tax", "Medicare Tax", 2 | "Medicare-for-all Tax", "Family Leave Tax", 3 | "Healthcare Premiums", "Healthcare Expenses") 4 | taxNamesEmp <- c("Employer Healthcare\nContribution", 5 | "Employer Payroll Tax", "Corporate Welfare", 6 | "Employer Medicare-for-all Tax") 7 | 8 | getBrackets <- function(filingStatus = c("Married/Joint", "Married/Separate", 9 | "Head of Household", "Single"), 10 | useCorporateWelfare = F, nKids = 0) { 11 | filingStatus <- match.arg(filingStatus) 12 | nilBracket <- data.frame(bottom = 0, cap = Inf, rate = 0, 13 | extra = 0, deduct = 0) 14 | 15 | #federal poverty level 16 | #http://familiesusa.org/product/federal-poverty-guidelines 17 | houseSize <- ifelse(filingStatus == "Married/Joint", 2, 1) + nKids 18 | fpl <- switch(pmin(houseSize, 8), 19 | 11770, 15930, 20090, 24250, 28410, 32570, 36730, 40890) 20 | 21 | #http://www.bankrate.com/finance/taxes/tax-brackets.aspx 22 | #https://www.irs.com/articles/2015-federal-tax-rates-personal-exemptions-and-standard-deductions 23 | #Married/jointly 2015 rate 24 | incomeBracketsCurrent <- switch( 25 | filingStatus, 26 | "Married/Joint" = data.frame( 27 | bottom = c(0, 18450, 74900, 151200, 230450, 411500, 464850), 28 | cap = c(18450, 74900, 151200, 230450, 411500, 464850, Inf), 29 | rate = c(.1, .15, .25, .28, .33, .35, .396), 30 | extra = 0, deduct = 1), 31 | "Single" = data.frame( 32 | bottom = c(0, 9225, 37450, 90750, 189300, 411500, 413200), 33 | cap = c(9225, 37450, 90750, 189300, 411500, 413200, Inf), 34 | rate = c(.1, .15, .25, .28, .33, .35, .396), 35 | extra = 0, deduct = 1), 36 | "Married/Separate" = data.frame( 37 | bottom = c(0, 9225, 37450, 75600, 115225, 205750, 232425), 38 | cap = c(9225, 37450, 75600, 115225, 205750, 232425, Inf), 39 | rate = c(.1, .15, .25, .28, .33, .35, .396), 40 | extra = 0, deduct = 1), 41 | "Head of Household" = data.frame( 42 | bottom = c(0, 13150, 50200, 129600, 209850, 411500, 439000), 43 | cap = c(13150, 50200, 129600, 209850, 411500, 439000, Inf), 44 | rate = c(.1, .15, .25, .28, .33, .35, .396), 45 | extra = 0, deduct = 1) 46 | ) 47 | 48 | # https://berniesanders.com/issues/medicare-for-all 49 | # https://berniesanders.com/wp-content/uploads/2016/01/friedman-memo-1.pdf 50 | incomeBracketsBernieNew <- data.frame( 51 | bottom = c(250000, 499999, 2000000, 10000000), 52 | cap = c(499999, 2000000, 10000000, Inf), 53 | rate = c(.37, .43, .48, .52), 54 | extra = 0, deduct = 1 55 | ) 56 | # Bernie's plan only changes brackets for incomes over $250K, so lower 57 | # brackets are held at current rate. For married/separate filers, the highest 58 | # bracket is under that 250K threshold (but at a higher rate than Bernie's 59 | # $250K bracket, so it is replaced with Bernies) 60 | oldBracketCutoff <- which(incomeBracketsCurrent$bottom > 250000)[1] - 1 61 | if(is.na(oldBracketCutoff)) { 62 | oldBracketCutoff <- nrow(incomeBracketsCurrent) - 1 63 | incomeBracketsBernieNew$bottom[1] <- 64 | incomeBracketsCurrent$bottom[nrow(incomeBracketsCurrent)] 65 | } 66 | incomeBracketsBernie <- 67 | rbind(incomeBracketsCurrent[seq_len(oldBracketCutoff), ], 68 | incomeBracketsBernieNew) 69 | incomeBracketsBernie$cap[oldBracketCutoff] <- 70 | incomeBracketsBernieNew$bottom[1] 71 | 72 | #https://www.irs.gov/publications/p15/ar02.html#en_US_2016_publink1000202402 73 | # Tax rates and the social security wage base limit. Social security and 74 | # Medicare taxes have different rates and only the social security tax has a 75 | # wage base limit. The wage base limit is the maximum wage subject to the tax 76 | # for the year. Determine the amount of withholding for social security and 77 | # Medicare taxes by multiplying each payment by the employee tax rate. There are 78 | # no withholding allowances for social security and Medicare taxes. 79 | # 80 | # For 2016, the social security tax rate is 6.2% (amount withheld) each for the 81 | # employer and employee (12.4% total). The social security wage base limit is 82 | # $118,500. The tax rate for Medicare is 1.45% (amount withheld) each for the 83 | # employee and employer (2.9% total). There is no wage base limit for Medicare 84 | # tax; all covered wages are subject to Medicare tax. 85 | # 86 | # Additional Medicare Tax withholding. In addition to withholding Medicare tax 87 | # at 1.45%, you must withhold a 0.9% Additional Medicare Tax from wages you pay 88 | # to an employee in excess of $200,000 in a calendar year. You are required to 89 | # begin withholding Additional Medicare Tax in the pay period in which you pay 90 | # wages in excess of $200,000 to an employee and continue to withhold it each 91 | # pay period until the end of the calendar year. Additional Medicare Tax is only 92 | # imposed on the employee. There is no employer share of Additional Medicare 93 | # Tax. All wages that are subject to Medicare tax are subject to Additional 94 | # Medicare Tax withholding if paid in excess of the $200,000 withholding 95 | # threshold. 96 | ssBracketsCurrent <- data.frame( 97 | bottom = c(0, 118500), 98 | cap = c(118500, Inf), 99 | rate = c(.062, 0), 100 | extra = 0, deduct = 0 101 | ) 102 | 103 | medicareBracketsCurrent <- data.frame( 104 | bottom = c(0, 200000), 105 | cap = c(200000, Inf), 106 | rate = c(.0145, .0145 + .009), 107 | extra = 0, deduct = 0 108 | ) 109 | 110 | #https://www.ssa.gov/oact/solvency/BSanders_20150323.pdf 111 | #earnings in the 118500 - 250000 range are not 112 | #taxed unless the total earnings are > 250000 113 | #($8,153 in taxes for the 118500 - 250000 range) 114 | #extra field compensates 115 | # Correction: I was wrong about the gap income being taxed for incomes 116 | # over 250000, changed extra back to 0 117 | ssBracketsBernie <- data.frame( 118 | bottom = c(0, 118500, 250000), 119 | cap = c(118500, 250000, Inf), 120 | rate = c(.062, 0, .062), 121 | extra = 0, 122 | deduct = 0 123 | ) 124 | 125 | 126 | mfaBracketsCurrent <- nilBracket 127 | 128 | #https://berniesanders.com/issues/medicare-for-all-2/ 129 | #https://berniesanders.com/wp-content/uploads/2016/01/friedman-memo-1.pdf 130 | # "The 2.2% income tax applies to taxable income as currently defined" 131 | mfaBracketsBernie <- data.frame( 132 | bottom = 0, cap = Inf, rate = .022, extra = 0, deduct = 1 133 | ) 134 | 135 | familyLeaveBracketsCurrent <- nilBracket 136 | 137 | #http://www.gillibrand.senate.gov/issues/paid-family-medical-leave 138 | familyLeaveBracketsBernie <- data.frame( 139 | bottom = c(0, 113700), 140 | cap = c(113700, Inf), 141 | rate = c(.002, 0), 142 | extra = 0, 143 | deduct = 0 144 | ) 145 | 146 | 147 | # Anyone earning above the medicaid threshold should eligible for 148 | # employer sponsored coverage under Obamacare, so Obamacare exchange plans 149 | # and tax credits are not included. 150 | # Using Milliman index for families because estimate of actual out-of-pocket 151 | # available. KFF's estimate for family premiums is ~$1,000 less 152 | # http://www.milliman.com/uploadedFiles/insight/Periodicals/mmi/2015-MMI.pdf 153 | # Using KFF for singles because milliman doesn't have info on singles 154 | # http://kff.org/health-costs/report/2015-employer-health-benefits-survey/ 155 | healthPremBracketsCurrent <- switch( 156 | as.character(houseSize > 1), 157 | "TRUE" = data.frame( 158 | bottom = c(0, fpl * 1.33), 159 | cap = c(fpl * 1.33, Inf), 160 | rate = c(0, 0), 161 | extra = c(0, 6408), 162 | deduct = 0), 163 | data.frame( 164 | bottom = c(0, fpl * 1.33), 165 | cap = c(fpl * 1.33, Inf), 166 | rate = c(0, 0), 167 | extra = c(0, 1071), 168 | deduct = 0) 169 | ) 170 | 171 | 172 | #out of pocket expenses set at 2.4% for medicaid recipients, or at the 173 | #national average of $4,065 for all others 174 | #(assumes state with obamacare medicaid expansion) 175 | #http://www.cbpp.org/research/out-of-pocket-medical-expenses-for-medicaid-beneficiaries-are-substantial-and-growing 176 | #http://www.milliman.com/uploadedFiles/insight/Periodicals/mmi/2015-MMI.pdf 177 | #page 7 178 | #http://obamacarefacts.com/obamacares-medicaid-expansion/ 179 | # No good out-of-pocket estimate for singles, using avg deductible from KFF 180 | # http://kff.org/health-costs/report/2015-employer-health-benefits-survey/ 181 | healthPocketBracketsCurrent <- switch( 182 | as.character(houseSize > 1), 183 | "TRUE" = data.frame( 184 | bottom = c(0, fpl * 1.33), 185 | cap = c(fpl * 1.33, Inf), 186 | rate = c(.024, 0), 187 | extra = c(0, max(4065 - .024 * fpl * 1.33, 0)), 188 | deduct = 0), 189 | data.frame( 190 | bottom = c(0, fpl * 1.33), 191 | cap = c(fpl * 1.33, Inf), 192 | rate = c(.024, 0), 193 | extra = c(0, max(1318 - .024 * fpl * 1.33, 0)), 194 | deduct = 0) 195 | ) 196 | 197 | #https://berniesanders.com/issues/medicare-for-all-2/ 198 | #https://berniesanders.com/wp-content/uploads/2016/01/friedman-memo-1.pdf 199 | # "It is assumed that 20% of out-of-pocket spending is for activities that 200 | # would not be covered because they are deemed not medically necessary" 201 | # Therefore, we keep 20% of the current plan OOP estimate 202 | healthPremBracketsBernie <- nilBracket 203 | 204 | #https://berniesanders.com/issues/medicare-for-all-2/ 205 | healthPocketBracketsBernie <- healthPocketBracketsCurrent 206 | healthPocketBracketsBernie$rate <- healthPocketBracketsBernie$rate * 0.2 207 | healthPocketBracketsBernie$extra <- healthPocketBracketsBernie$extra * 0.2 208 | 209 | # Using Milliman index for families because estimate of actual out-of-pocket 210 | # available. Differences between KFF and milliman for employer contribution 211 | # are minimal 212 | # http://www.milliman.com/uploadedFiles/insight/Periodicals/mmi/2015-MMI.pdf 213 | # Using KFF for singles because milliman doesn't have info on singles 214 | # http://kff.org/health-costs/report/2015-employer-health-benefits-survey/ 215 | healthEmpBracketsCurrent <- switch( 216 | as.character(houseSize > 1), 217 | "TRUE" = data.frame( 218 | bottom = c(0, fpl * 1.33), 219 | cap = c(fpl * 1.33, Inf), 220 | rate = 0, 221 | extra = c(0, 14198), 222 | deduct = 0), 223 | data.frame( 224 | bottom = c(0, fpl * 1.33), 225 | cap = c(fpl * 1.33, Inf), 226 | rate = 0, 227 | extra = c(0, 5179), 228 | deduct = 0) 229 | ) 230 | 231 | # https://berniesanders.com/issues/medicare-for-all-2/ 232 | healthEmpBracketsBernie <- nilBracket 233 | 234 | # https://www.irs.gov/publications/p15/ar02.html#en_US_2016_publink1000202402 235 | # https://www.irs.gov/pub/irs-pdf/f940.pdf 236 | # For unemployment tax, including the full 6% as discounts apply only when 237 | # equivalent amounts are paid to state unemployment program 238 | payrollTaxBracketsCurrent <- data.frame( 239 | bottom = c(0, 7000, 118500), 240 | cap = c(7000, 118500, Inf), 241 | #unemployment tax ends at $7,000, soc sec tax ends at $118,500 242 | rate = c(.062 + .0145 + 0.06, .062 + .0145, .0145), 243 | extra = 0, deduct = 0 244 | ) 245 | 246 | #https://www.ssa.gov/oact/solvency/BSanders_20150323.pdf 247 | # only difference is the Soc Sec cap removal - follows the same pattern as 248 | # invidiual soc sec tax 249 | payrollTaxBracketsBernie <- data.frame( 250 | bottom = c(0, 7000, 118500, 250000), 251 | cap = c(7000, 118500, 250000, Inf), 252 | #unemployment tax ends at $7,000, 253 | #soc sec tax ends at $118,500 and resumes at $250,000 (with backlog) 254 | #medicare for all tax added to all brackets 255 | rate = c(.062 + .0145 + 0.06, .062 + .0145, .0145, .0145 + .062), 256 | extra = c(0, 0, 0, 8153), 257 | deduct = 0 258 | ) 259 | 260 | payrollMFABracketsCurrent <- nilBracket 261 | 262 | # https://berniesanders.com/issues/medicare-for-all-2/ 263 | payrollMFABracketsBernie <- data.frame( 264 | bottom = 0, cap = Inf, rate = .062, extra = 0, deduct = 0 265 | ) 266 | 267 | # not currently used - represents the what employers save by paying so little 268 | # that their employees qualify for medicare 269 | corpWelfareGapCurrent <- data.frame( 270 | bottom = c(0, fpl * 1.33), 271 | cap = c(fpl * 1.33, Inf), 272 | rate = 0, 273 | extra = c(14198, -14198), 274 | deduct = 0 275 | ) 276 | 277 | corpWelfareGapBernie <- nilBracket 278 | 279 | currentIndBrackets <- list(incomeBracketsCurrent, 280 | ssBracketsCurrent, 281 | medicareBracketsCurrent, 282 | mfaBracketsCurrent, 283 | familyLeaveBracketsCurrent, 284 | healthPremBracketsCurrent, 285 | healthPocketBracketsCurrent) 286 | currentEmpBrackets <- list(healthEmpBracketsCurrent, 287 | payrollTaxBracketsCurrent, 288 | corpWelfareGapCurrent, 289 | payrollMFABracketsCurrent) 290 | 291 | bernieIndBrackets <- list(incomeBracketsBernie, 292 | ssBracketsBernie, 293 | medicareBracketsCurrent, 294 | mfaBracketsBernie, 295 | familyLeaveBracketsBernie, 296 | healthPremBracketsBernie, 297 | healthPocketBracketsBernie) 298 | bernieEmpBrackets <- list(healthEmpBracketsBernie, 299 | payrollTaxBracketsBernie, 300 | corpWelfareGapBernie, 301 | payrollMFABracketsBernie) 302 | 303 | names(currentIndBrackets) <- taxNamesInd 304 | names(bernieIndBrackets) <- taxNamesInd 305 | names(currentEmpBrackets) <- taxNamesEmp 306 | names(bernieEmpBrackets) <- taxNamesEmp 307 | if(!useCorporateWelfare) { 308 | currentEmpBrackets$`Corporate Welfare` <- NULL 309 | bernieEmpBrackets$`Corporate Welfare` <- NULL 310 | } 311 | list(currentIndBrackets = currentIndBrackets, 312 | bernieIndBrackets = bernieIndBrackets, 313 | currentEmpBrackets = currentEmpBrackets, 314 | bernieEmpBrackets = bernieEmpBrackets) 315 | } -------------------------------------------------------------------------------- /BernieTaxExport.csv: -------------------------------------------------------------------------------- 1 | "Income","Income Percentile","Income Tax with Bernie","Social Security Tax with Bernie","Medicare Tax with Bernie","Medicare-for-all Tax with Bernie","Family Leave Tax with Bernie","Healthcare Premiums with Bernie","Healthcare Expenses with Bernie","Total Tax with Bernie","Effective Tax Rate with Bernie","Income Tax at Present","Social Security Tax at Present","Medicare Tax at Present","Medicare-for-all Tax at Present","Family Leave Tax at Present","Healthcare Premiums at Present","Healthcare Expenses at Present","Total Tax at Present","Effective Tax Rate at Present" 2 | 8000,0.196532562614193,-503,496,116,176,16,0,0,301,0.037625,-503,496,116,0,0,0,192,301,0.037625 3 | 10000,0.220769909615664,-503,620,145,220,20,0,0,502,0.0502,-503,620,145,0,0,0,240,502,0.0502 4 | 11889.8112063558,0.25,-344.018879364416,737.168294794062,172.40226249216,261.575846539829,23.7796224127117,0,0,850.907146874347,0.0715660772157159,-344.018879364416,737.168294794062,172.40226249216,0,0,0,285.35546895254,850.907146874347,0.0715660772157159 5 | 12000,0.251704312254434,-333,744,174,264,24,0,0,873,0.07275,-333,744,174,0,0,0,288,873,0.07275 6 | 14000,0.275765573107831,-133,868,203,308,28,0,0,1274,0.091,-133,868,203,0,0,0,336,1274,0.091 7 | 16000,0.301707937329216,67,992,232,352,32,0,0,1675,0.1046875,67,992,232,0,0,1071,1318,3680,0.23 8 | 18000,0.330155493394991,267,1116,261,396,36,0,0,2076,0.115333333333333,267,1116,261,0,0,1071,1318,4033,0.224055555555556 9 | 20000,0.353663670024415,490.75,1240,290,440,40,0,0,2500.75,0.1250375,490.75,1240,290,0,0,1071,1318,4409.75,0.2204875 10 | 22000,0.387198037091532,790.75,1364,319,484,44,0,0,3001.75,0.136443181818182,790.75,1364,319,0,0,1071,1318,4862.75,0.221034090909091 11 | 24000,0.410733341956764,1357.878,1488,348,528,48,0,0,3769.878,0.15707825,1357.878,1488,348,0,0,1071,1318,5582.878,0.232619916666667 12 | 26000,0.435350092971365,1893.75,1612,377,572,52,0,0,4506.75,0.173336538461538,1893.75,1612,377,0,0,1071,1318,6271.75,0.241221153846154 13 | 28000,0.46150086180413,2193.75,1736,406,616,56,0,0,5007.75,0.178848214285714,2193.75,1736,406,0,0,1071,1318,6724.75,0.240169642857143 14 | 30000,0.479093498472036,2493.75,1860,435,660,60,0,0,5508.75,0.183625,2493.75,1860,435,0,0,1071,1318,7177.75,0.239258333333333 15 | 31298.7187625552,0.5,2688.55781438329,1940.52056327843,453.831422057051,688.571812776215,62.5974375251105,0,0,5834.07905002009,0.186399932031716,2688.55781438329,1940.52056327843,453.831422057051,0,0,1071,1318,7471.90979971876,0.238728935085289 16 | 32000,0.51128907788575,2793.75,1984,464,704,64,0,0,6009.75,0.1878046875,2793.75,1984,464,0,0,1071,1318,7630.75,0.2384609375 17 | 34000,0.52958304849063,3093.75,2108,493,748,68,0,0,6510.75,0.191492647058824,3093.75,2108,493,0,0,1071,1318,8083.75,0.237757352941176 18 | 36000,0.549833123676169,3393.75,2232,522,792,72,0,0,7011.75,0.194770833333333,3393.75,2232,522,0,0,1071,1318,8536.75,0.237131944444444 19 | 38000,0.573198431613498,3693.75,2356,551,836,76,0,0,7512.75,0.197703947368421,3693.75,2356,551,0,0,1071,1318,8989.75,0.236572368421053 20 | 40000,0.586250945074135,3993.75,2480,580,880,80,0,0,8013.75,0.20034375,3993.75,2480,580,0,0,1071,1318,9442.75,0.23606875 21 | 42000,0.614132653160218,4293.75,2604,609,924,84,0,0,8514.75,0.202732142857143,4293.75,2604,609,0,0,1071,1318,9895.75,0.235613095238095 22 | 44000,0.629049557779682,4593.75,2728,638,968,88,0,0,9015.75,0.204903409090909,4593.75,2728,638,0,0,1071,1318,10348.75,0.235198863636364 23 | 46000,0.643388662344172,4893.75,2852,667,1012,92,0,0,9516.75,0.206885869565217,4893.75,2852,667,0,0,1071,1318,10801.75,0.234820652173913 24 | 48000,0.659629951331512,5218.75,2976,696,1056,96,0,0,10042.75,0.209223958333333,5218.75,2976,696,0,0,1071,1318,11279.75,0.234994791666667 25 | 50000,0.670424816078387,5718.75,3100,725,1100,100,0,0,10743.75,0.214875,5718.75,3100,725,0,0,1071,1318,11932.75,0.238655 26 | 52000,0.695118010574482,6218.75,3224,754,1144,104,0,0,11444.75,0.220091346153846,6218.75,3224,754,0,0,1071,1318,12585.75,0.242033653846154 27 | 54000,0.708147250472941,6718.75,3348,783,1188,108,0,0,12145.75,0.224921296296296,6718.75,3348,783,0,0,1071,1318,13238.75,0.245162037037037 28 | 56000,0.719833453522402,7218.75,3472,812,1232,112,0,0,12846.75,0.22940625,7218.75,3472,812,0,0,1071,1318,13891.75,0.248066964285714 29 | 58000,0.732244357850825,7718.75,3596,841,1276,116,0,0,13547.75,0.233581896551724,7718.75,3596,841,0,0,1071,1318,14544.75,0.250771551724138 30 | 60000,0.739261115332999,8218.75,3720,870,1320,120,0,0,14248.75,0.237479166666667,8218.75,3720,870,0,0,1071,1318,15197.75,0.253295833333333 31 | 61140.7897629681,0.75,8503.94744074201,3790.72896530402,886.541451563037,1345.0973747853,122.281579525936,0,0,14648.5968119203,0.239587955417493,8503.94744074201,3790.72896530402,886.541451563037,0,0,1071,1318,15570.2178576091,0.254661706496956 32 | 62000,0.758088220932301,8718.75,3844,899,1364,124,0,0,14949.75,0.241125,8718.75,3844,899,0,0,1071,1318,15850.75,0.255657258064516 33 | 64000,0.767712306174915,9218.75,3968,928,1408,128,0,0,15650.75,0.24454296875,9218.75,3968,928,0,0,1071,1318,16503.75,0.25787109375 34 | 66000,0.776711132310379,9718.75,4092,957,1452,132,0,0,16351.75,0.247753787878788,9718.75,4092,957,0,0,1071,1318,17156.75,0.259950757575758 35 | 68000,0.786606693938267,10218.75,4216,986,1496,136,0,0,17052.75,0.250775735294118,10218.75,4216,986,0,0,1071,1318,17809.75,0.261908088235294 36 | 70000,0.791920387407635,10718.75,4340,1015,1540,140,0,0,17753.75,0.253625,10718.75,4340,1015,0,0,1071,1318,18462.75,0.263753571428571 37 | 72000,0.804862001390528,11218.75,4464,1044,1584,144,0,0,18454.75,0.256315972222222,11218.75,4464,1044,0,0,1071,1318,19115.75,0.265496527777778 38 | 74000,0.811901256326095,11718.75,4588,1073,1628,148,0,0,19155.75,0.258861486486486,11718.75,4588,1073,0,0,1071,1318,19768.75,0.26714527027027 39 | 76000,0.819888382621631,12218.75,4712,1102,1672,152,0,0,19856.75,0.261273026315789,12218.75,4712,1102,0,0,1071,1318,20421.75,0.268707236842105 40 | 78000,0.829172609827477,12718.75,4836,1131,1716,156,0,0,20557.75,0.263560897435897,12718.75,4836,1131,0,0,1071,1318,21074.75,0.270189102564103 41 | 80000,0.833651494817857,13218.75,4960,1160,1760,160,0,0,21258.75,0.265734375,13218.75,4960,1160,0,0,1071,1318,21727.75,0.271596875 42 | 82000,0.844775720730189,13718.75,5084,1189,1804,164,0,0,21959.75,0.267801829268293,13718.75,5084,1189,0,0,1071,1318,22380.75,0.272935975609756 43 | 84000,0.850580057238023,14218.75,5208,1218,1848,168,0,0,22660.75,0.269770833333333,14218.75,5208,1218,0,0,1071,1318,23033.75,0.27421130952381 44 | 86000,0.855713172829725,14718.75,5332,1247,1892,172,0,0,23361.75,0.271648255813953,14718.75,5332,1247,0,0,1071,1318,23686.75,0.275427325581395 45 | 88000,0.861171885459278,15218.75,5456,1276,1936,176,0,0,24062.75,0.273440340909091,15218.75,5456,1276,0,0,1071,1318,24339.75,0.276588068181818 46 | 90000,0.86433051886106,15718.75,5580,1305,1980,180,0,0,24763.75,0.275152777777778,15718.75,5580,1305,0,0,1071,1318,24992.75,0.277697222222222 47 | 92000,0.872402050220706,16218.75,5704,1334,2024,184,0,0,25464.75,0.276790760869565,16218.75,5704,1334,0,0,1071,1318,25645.75,0.278758152173913 48 | 94000,0.876590450628163,16718.75,5828,1363,2068,188,0,0,26165.75,0.278359042553191,16718.75,5828,1363,0,0,1071,1318,26298.75,0.279773936170213 49 | 96000,0.880047927951234,17218.75,5952,1392,2112,192,0,0,26866.75,0.279861979166667,17218.75,5952,1392,0,0,1071,1318,26951.75,0.280747395833333 50 | 98000,0.883824512102446,17718.75,6076,1421,2156,196,0,0,27567.75,0.281303571428571,17718.75,6076,1421,0,0,1071,1318,27604.75,0.28168112244898 51 | 1e+05,0.886883438000226,18218.75,6200,1450,2200,200,0,0,28268.75,0.2826875,18218.75,6200,1450,0,0,1071,1318,28257.75,0.2825775 52 | 102000,0.889470143903504,18747.25,6324,1479,2244,204,0,0,28998.25,0.284296568627451,18747.25,6324,1479,0,0,1071,1318,28939.25,0.283718137254902 53 | 104000,0.892056849806781,19307.25,6448,1508,2288,208,0,0,29759.25,0.286146634615385,19307.25,6448,1508,0,0,1071,1318,29652.25,0.285117788461538 54 | 106000,0.894643555710059,19867.25,6572,1537,2332,212,0,0,30520.25,0.287926886792453,19867.25,6572,1537,0,0,1071,1318,30365.25,0.286464622641509 55 | 108000,0.897230261613336,20427.25,6696,1566,2376,216,0,0,31281.25,0.289641203703704,20427.25,6696,1566,0,0,1071,1318,31078.25,0.287761574074074 56 | 110000,0.899816967516614,20987.25,6820,1595,2420,220,0,0,32042.25,0.291293181818182,20987.25,6820,1595,0,0,1071,1318,31791.25,0.289011363636364 57 | 112000,0.902403673419891,21547.25,6944,1624,2464,224,0,0,32803.25,0.292886160714286,21547.25,6944,1624,0,0,1071,1318,32504.25,0.290216517857143 58 | 114000,0.904990379323168,22107.25,7068,1653,2508,227.4,0,0,33563.65,0.29441798245614,22107.25,7068,1653,0,0,1071,1318,33217.25,0.291379385964912 59 | 116000,0.907577085226446,22667.25,7192,1682,2552,227.4,0,0,34320.65,0.295867672413793,22667.25,7192,1682,0,0,1071,1318,33930.25,0.292502155172414 60 | 118000,0.910163791129723,23227.25,7316,1711,2596,227.4,0,0,35077.65,0.297268220338983,23227.25,7316,1711,0,0,1071,1318,34643.25,0.29358686440678 61 | 120000,0.912750497033001,23787.25,7347,1740,2640,227.4,0,0,35741.65,0.297847083333333,23787.25,7347,1740,0,0,1071,1318,35263.25,0.293860416666667 62 | 122000,0.915337202936278,24347.25,7347,1769,2684,227.4,0,0,36374.65,0.298152868852459,24347.25,7347,1769,0,0,1071,1318,35852.25,0.293870901639344 63 | 124000,0.917923908839556,24907.25,7347,1798,2728,227.4,0,0,37007.65,0.298448790322581,24907.25,7347,1798,0,0,1071,1318,36441.25,0.293881048387097 64 | 126000,0.920510614742833,25467.25,7347,1827,2772,227.4,0,0,37640.65,0.298735317460317,25467.25,7347,1827,0,0,1071,1318,37030.25,0.293890873015873 65 | 128000,0.92309732064611,26027.25,7347,1856,2816,227.4,0,0,38273.65,0.299012890625,26027.25,7347,1856,0,0,1071,1318,37619.25,0.293900390625 66 | 130000,0.925684026549388,26587.25,7347,1885,2860,227.4,0,0,38906.65,0.299281923076923,26587.25,7347,1885,0,0,1071,1318,38208.25,0.293909615384615 67 | 132000,0.928270732452665,27147.25,7347,1914,2904,227.4,0,0,39539.65,0.299542803030303,27147.25,7347,1914,0,0,1071,1318,38797.25,0.293918560606061 68 | 134000,0.930857438355943,27707.25,7347,1943,2948,227.4,0,0,40172.65,0.299795895522388,27707.25,7347,1943,0,0,1071,1318,39386.25,0.29392723880597 69 | 136000,0.93344414425922,28267.25,7347,1972,2992,227.4,0,0,40805.65,0.300041544117647,28267.25,7347,1972,0,0,1071,1318,39975.25,0.293935661764706 70 | 138000,0.936030850162498,28827.25,7347,2001,3036,227.4,0,0,41438.65,0.300280072463768,28827.25,7347,2001,0,0,1071,1318,40564.25,0.29394384057971 71 | 140000,0.938617556065775,29387.25,7347,2030,3080,227.4,0,0,42071.65,0.300511785714286,29387.25,7347,2030,0,0,1071,1318,41153.25,0.293951785714286 72 | 142000,0.941204261969053,29947.25,7347,2059,3124,227.4,0,0,42704.65,0.300736971830986,29947.25,7347,2059,0,0,1071,1318,41742.25,0.293959507042254 73 | 144000,0.94379096787233,30507.25,7347,2088,3168,227.4,0,0,43337.65,0.300955902777778,30507.25,7347,2088,0,0,1071,1318,42331.25,0.293967013888889 74 | 146000,0.946377673775608,31067.25,7347,2117,3212,227.4,0,0,43970.65,0.301168835616438,31067.25,7347,2117,0,0,1071,1318,42920.25,0.293974315068493 75 | 148000,0.948964379678885,31627.25,7347,2146,3256,227.4,0,0,44603.65,0.301376013513514,31627.25,7347,2146,0,0,1071,1318,43509.25,0.293981418918919 76 | 150000,0.951550283118017,32187.25,7347,2175,3300,227.4,0,0,45236.65,0.301577666666667,32187.25,7347,2175,0,0,1071,1318,44098.25,0.293988333333333 77 | 152000,0.952532060730512,32747.25,7347,2204,3344,227.4,0,0,45869.65,0.301774013157895,32747.25,7347,2204,0,0,1071,1318,44687.25,0.293995065789474 78 | 154000,0.953513838343008,33307.25,7347,2233,3388,227.4,0,0,46502.65,0.30196525974026,33307.25,7347,2233,0,0,1071,1318,45276.25,0.294001623376623 79 | 156000,0.954495615955503,33867.25,7347,2262,3432,227.4,0,0,47135.65,0.302151602564103,33867.25,7347,2262,0,0,1071,1318,45865.25,0.294008012820513 80 | 158000,0.955477393567998,34427.25,7347,2291,3476,227.4,0,0,47768.65,0.302333227848101,34427.25,7347,2291,0,0,1071,1318,46454.25,0.294014240506329 81 | 160000,0.956459171180494,34987.25,7347,2320,3520,227.4,0,0,48401.65,0.3025103125,34987.25,7347,2320,0,0,1071,1318,47043.25,0.2940203125 82 | 162000,0.957440948792989,35547.25,7347,2349,3564,227.4,0,0,49034.65,0.302683024691358,35547.25,7347,2349,0,0,1071,1318,47632.25,0.294026234567901 83 | 164000,0.958422726405484,36107.25,7347,2378,3608,227.4,0,0,49667.65,0.302851524390244,36107.25,7347,2378,0,0,1071,1318,48221.25,0.294032012195122 84 | 166000,0.95940450401798,36667.25,7347,2407,3652,227.4,0,0,50300.65,0.303015963855422,36667.25,7347,2407,0,0,1071,1318,48810.25,0.29403765060241 85 | 168000,0.960386281630475,37227.25,7347,2436,3696,227.4,0,0,50933.65,0.303176488095238,37227.25,7347,2436,0,0,1071,1318,49399.25,0.294043154761905 86 | 170000,0.961368059242971,37787.25,7347,2465,3740,227.4,0,0,51566.65,0.303333235294118,37787.25,7347,2465,0,0,1071,1318,49988.25,0.294048529411765 87 | 172000,0.962349836855466,38347.25,7347,2494,3784,227.4,0,0,52199.65,0.303486337209302,38347.25,7347,2494,0,0,1071,1318,50577.25,0.294053779069767 88 | 174000,0.963331614467961,38907.25,7347,2523,3828,227.4,0,0,52832.65,0.30363591954023,38907.25,7347,2523,0,0,1071,1318,51166.25,0.294058908045977 89 | 176000,0.964313392080457,39467.25,7347,2552,3872,227.4,0,0,53465.65,0.303782102272727,39467.25,7347,2552,0,0,1071,1318,51755.25,0.294063920454545 90 | 178000,0.965295169692952,40027.25,7347,2581,3916,227.4,0,0,54098.65,0.303925,40027.25,7347,2581,0,0,1071,1318,52344.25,0.294068820224719 91 | 180000,0.966276947305447,40587.25,7347,2610,3960,227.4,0,0,54731.65,0.304064722222222,40587.25,7347,2610,0,0,1071,1318,52933.25,0.294073611111111 92 | 182000,0.967258724917943,41147.25,7347,2639,4004,227.4,0,0,55364.65,0.304201373626374,41147.25,7347,2639,0,0,1071,1318,53522.25,0.294078296703297 93 | 184000,0.968240502530438,41707.25,7347,2668,4048,227.4,0,0,55997.65,0.304335054347826,41707.25,7347,2668,0,0,1071,1318,54111.25,0.294082880434783 94 | 186000,0.969222280142933,42267.25,7347,2697,4092,227.4,0,0,56630.65,0.304465860215054,42267.25,7347,2697,0,0,1071,1318,54700.25,0.294087365591398 95 | 188000,0.970204057755429,42827.25,7347,2726,4136,227.4,0,0,57263.65,0.304593882978723,42827.25,7347,2726,0,0,1071,1318,55289.25,0.294091755319149 96 | 190000,0.971185835367924,43387.25,7347,2755,4180,227.4,0,0,57896.65,0.304719210526316,43387.25,7347,2755,0,0,1071,1318,55878.25,0.294096052631579 97 | 192000,0.972167612980419,43947.25,7347,2784,4224,227.4,0,0,58529.65,0.304841927083333,43947.25,7347,2784,0,0,1071,1318,56467.25,0.294100260416667 98 | 194000,0.973149390592915,44507.25,7347,2813,4268,227.4,0,0,59162.65,0.304962113402062,44507.25,7347,2813,0,0,1071,1318,57056.25,0.294104381443299 99 | 196000,0.97413116820541,45067.25,7347,2842,4312,227.4,0,0,59795.65,0.305079846938776,45067.25,7347,2842,0,0,1071,1318,57645.25,0.294108418367347 100 | 198000,0.975112945817905,45627.25,7347,2871,4356,227.4,0,0,60428.65,0.305195202020202,45627.25,7347,2871,0,0,1071,1318,58234.25,0.294112373737374 101 | 2e+05,0.97609443158116,46207.25,7347,2900,4400,227.4,0,0,61081.65,0.30540825,46207.25,7347,2900,0,0,1071,1318,58843.25,0.29421625 102 | 202000,0.976492510711918,46867.25,7347,2947,4444,227.4,0,0,61832.65,0.306102227722772,46867.25,7347,2947,0,0,1071,1318,59550.25,0.294803217821782 103 | 204000,0.976890589842676,47527.25,7347,2994,4488,227.4,0,0,62583.65,0.306782598039216,47527.25,7347,2994,0,0,1071,1318,60257.25,0.295378676470588 104 | 206000,0.977288668973434,48187.25,7347,3041,4532,227.4,0,0,63334.65,0.307449757281553,48187.25,7347,3041,0,0,1071,1318,60964.25,0.295942961165049 105 | 208000,0.977686748104193,48847.25,7347,3088,4576,227.4,0,0,64085.65,0.308104086538462,48847.25,7347,3088,0,0,1071,1318,61671.25,0.296496394230769 106 | 210000,0.978084827234951,49507.25,7347,3135,4620,227.4,0,0,64836.65,0.308745952380952,49507.25,7347,3135,0,0,1071,1318,62378.25,0.297039285714286 107 | 212000,0.978482906365709,50167.25,7347,3182,4664,227.4,0,0,65587.65,0.30937570754717,50167.25,7347,3182,0,0,1071,1318,63085.25,0.297571933962264 108 | 214000,0.978880985496467,50827.25,7347,3229,4708,227.4,0,0,66338.65,0.309993691588785,50827.25,7347,3229,0,0,1071,1318,63792.25,0.298094626168224 109 | 216000,0.979279064627225,51487.25,7347,3276,4752,227.4,0,0,67089.65,0.310600231481481,51487.25,7347,3276,0,0,1071,1318,64499.25,0.298607638888889 110 | 218000,0.979677143757983,52147.25,7347,3323,4796,227.4,0,0,67840.65,0.311195642201835,52147.25,7347,3323,0,0,1071,1318,65206.25,0.29911123853211 111 | 220000,0.980075222888741,52807.25,7347,3370,4840,227.4,0,0,68591.65,0.311780227272727,52807.25,7347,3370,0,0,1071,1318,65913.25,0.299605681818182 112 | 222000,0.9804733020195,53467.25,7347,3417,4884,227.4,0,0,69342.65,0.312354279279279,53467.25,7347,3417,0,0,1071,1318,66620.25,0.300091216216216 113 | 224000,0.980871381150258,54127.25,7347,3464,4928,227.4,0,0,70093.65,0.312918080357143,54127.25,7347,3464,0,0,1071,1318,67327.25,0.300568080357143 114 | 226000,0.981269460281016,54787.25,7347,3511,4972,227.4,0,0,70844.65,0.313471902654867,54787.25,7347,3511,0,0,1071,1318,68034.25,0.301036504424779 115 | 228000,0.981667539411774,55447.25,7347,3558,5016,227.4,0,0,71595.65,0.31401600877193,55447.25,7347,3558,0,0,1071,1318,68741.25,0.301496710526316 116 | 230000,0.982065618542532,56107.25,7347,3605,5060,227.4,0,0,72346.65,0.314550652173913,56107.25,7347,3605,0,0,1071,1318,69448.25,0.301948913043478 117 | 232000,0.98246369767329,56767.25,7347,3652,5104,227.4,0,0,73097.65,0.315076077586207,56767.25,7347,3652,0,0,1071,1318,70155.25,0.302393318965517 118 | 234000,0.982861776804049,57427.25,7347,3699,5148,227.4,0,0,73848.65,0.315592521367521,57427.25,7347,3699,0,0,1071,1318,70862.25,0.302830128205128 119 | 236000,0.983259855934807,58087.25,7347,3746,5192,227.4,0,0,74599.65,0.316100211864407,58087.25,7347,3746,0,0,1071,1318,71569.25,0.303259533898305 120 | 238000,0.983657935065565,58747.25,7347,3793,5236,227.4,0,0,75350.65,0.316599369747899,58747.25,7347,3793,0,0,1071,1318,72276.25,0.303681722689076 121 | 240000,0.984056014196323,59407.25,7347,3840,5280,227.4,0,0,76101.65,0.317090208333333,59407.25,7347,3840,0,0,1071,1318,72983.25,0.304096875 122 | 242000,0.984454093327081,60067.25,7347,3887,5324,227.4,0,0,76852.65,0.317572933884297,60067.25,7347,3887,0,0,1071,1318,73690.25,0.304505165289256 123 | 244000,0.984852172457839,60727.25,7347,3934,5368,227.4,0,0,77603.65,0.318047745901639,60727.25,7347,3934,0,0,1071,1318,74397.25,0.304906762295082 124 | 246000,0.985250251588598,61387.25,7347,3981,5412,227.4,0,0,78354.65,0.318514837398374,61387.25,7347,3981,0,0,1071,1318,75104.25,0.305301829268293 125 | 248000,0.985648330719356,62047.25,7347,4028,5456,227.4,0,0,79105.65,0.31897439516129,62047.25,7347,4028,0,0,1071,1318,75811.25,0.305690524193548 126 | 250000,0.986046287137089,62707.25,7347,4075,5500,227.4,0,0,79856.65,0.3194266,62707.25,7347,4075,0,0,1071,1318,76518.25,0.306073 127 | 252000,0.986198940218471,63367.25,15624,4122,5544,227.4,0,0,88884.65,0.352716865079365,63367.25,7347,4122,0,0,1071,1318,77225.25,0.306449404761905 128 | 254000,0.986351593299852,64027.25,15748,4169,5588,227.4,0,0,89759.65,0.353384448818898,64027.25,7347,4169,0,0,1071,1318,77932.25,0.306819881889764 129 | 256000,0.986504246381233,64687.25,15872,4216,5632,227.4,0,0,90634.65,0.3540416015625,64687.25,7347,4216,0,0,1071,1318,78639.25,0.3071845703125 130 | 258000,0.986656899462615,65347.25,15996,4263,5676,227.4,0,0,91509.65,0.354688565891473,65347.25,7347,4263,0,0,1071,1318,79346.25,0.307543604651163 131 | 260000,0.986809552543996,66033.65,16120,4310,5720,227.4,0,0,92411.05,0.355427115384615,66033.65,7347,4310,0,0,1071,1318,80079.65,0.307998653846154 132 | 262000,0.986962205625378,66794.45,16244,4357,5764,227.4,0,0,93386.85,0.356438358778626,66720.05,7347,4357,0,0,1071,1318,80813.05,0.308446755725191 133 | 264000,0.987114858706759,67564.05,16368,4404,5808,227.4,0,0,94371.45,0.357467613636364,67406.45,7347,4404,0,0,1071,1318,81546.45,0.308888068181818 134 | 266000,0.98726751178814,68333.65,16492,4451,5852,227.4,0,0,95356.05,0.358481390977444,68092.85,7347,4451,0,0,1071,1318,82279.85,0.309322744360902 135 | 268000,0.987420164869522,69073.65,16616,4498,5896,227.4,0,0,96311.05,0.359369589552239,68752.85,7347,4498,0,0,1071,1318,82986.85,0.309652425373134 136 | 270000,0.987572817950903,69843.25,16740,4545,5940,227.4,0,0,97295.65,0.360354259259259,69439.25,7347,4545,0,0,1071,1318,83720.25,0.310075 137 | 272000,0.987725471032285,70612.85,16864,4592,5984,227.4,0,0,98280.25,0.361324448529412,70125.65,7347,4592,0,0,1071,1318,84453.65,0.310491360294118 138 | 274000,0.987878124113666,71382.45,16988,4639,6028,227.4,0,0,99264.85,0.362280474452555,70812.05,7347,4639,0,0,1071,1318,85187.05,0.310901642335766 139 | 276000,0.988030777195047,72152.05,17112,4686,6072,227.4,0,0,100249.45,0.363222644927536,71498.45,7347,4686,0,0,1071,1318,85920.45,0.31130597826087 140 | 278000,0.988183430276429,72892.05,17236,4733,6116,227.4,0,0,101204.45,0.364044784172662,72158.45,7347,4733,0,0,1071,1318,86627.45,0.311609532374101 141 | 280000,0.98833608335781,73661.65,17360,4780,6160,227.4,0,0,102189.05,0.364960892857143,72844.85,7347,4780,0,0,1071,1318,87360.85,0.312003035714286 142 | 282000,0.988488736439192,74431.25,17484,4827,6204,227.4,0,0,103173.65,0.365864007092199,73531.25,7347,4827,0,0,1071,1318,88094.25,0.312390957446809 143 | 284000,0.988641389520573,75200.85,17608,4874,6248,227.4,0,0,104158.25,0.366754401408451,74217.65,7347,4874,0,0,1071,1318,88827.65,0.312773415492958 144 | 286000,0.988794042601954,75970.45,17732,4921,6292,227.4,0,0,105142.85,0.367632342657343,74904.05,7347,4921,0,0,1071,1318,89561.05,0.313150524475524 145 | 288000,0.988946695683336,76710.45,17856,4968,6336,227.4,0,0,106097.85,0.3683953125,75564.05,7347,4968,0,0,1071,1318,90268.05,0.313430729166667 146 | 290000,0.989099348764717,77480.05,17980,5015,6380,227.4,0,0,107082.45,0.369249827586207,76250.45,7347,5015,0,0,1071,1318,91001.45,0.313798103448276 147 | 292000,0.989252001846099,78249.65,18104,5062,6424,227.4,0,0,108067.05,0.370092636986301,76936.85,7347,5062,0,0,1071,1318,91734.85,0.314160445205479 148 | 294000,0.98940465492748,79019.25,18228,5109,6468,227.4,0,0,109051.65,0.370923979591837,77623.25,7347,5109,0,0,1071,1318,92468.25,0.314517857142857 149 | 296000,0.989557308008861,79788.85,18352,5156,6512,227.4,0,0,110036.25,0.371744087837838,78309.65,7347,5156,0,0,1071,1318,93201.65,0.314870439189189 150 | 298000,0.989709961090243,80528.85,18476,5203,6556,227.4,0,0,110991.25,0.372453859060403,78969.65,7347,5203,0,0,1071,1318,93908.65,0.315129697986577 151 | 3e+05,0.989862614171624,81298.45,18600,5250,6600,227.4,0,0,111975.85,0.373252833333333,79656.05,7347,5250,0,0,1071,1318,94642.05,0.3154735 152 | 302000,0.990015267253006,82068.05,18724,5297,6644,227.4,0,0,112960.45,0.374041225165563,80342.45,7347,5297,0,0,1071,1318,95375.45,0.315812748344371 153 | 304000,0.990167920334387,82837.65,18848,5344,6688,227.4,0,0,113945.05,0.374819243421053,81028.85,7347,5344,0,0,1071,1318,96108.85,0.316147532894737 154 | 306000,0.990320573415768,83607.25,18972,5391,6732,227.4,0,0,114929.65,0.375587091503268,81715.25,7347,5391,0,0,1071,1318,96842.25,0.316477941176471 155 | 308000,0.99047322649715,84347.25,19096,5438,6776,227.4,0,0,115884.65,0.376248863636364,82375.25,7347,5438,0,0,1071,1318,97549.25,0.316718344155844 156 | 310000,0.990625879578531,85116.85,19220,5485,6820,227.4,0,0,116869.25,0.376997580645161,83061.65,7347,5485,0,0,1071,1318,98282.65,0.317040806451613 157 | 312000,0.990778532659913,85886.45,19344,5532,6864,227.4,0,0,117853.85,0.377736698717949,83748.05,7347,5532,0,0,1071,1318,99016.05,0.317359134615385 158 | 314000,0.990931185741294,86656.05,19468,5579,6908,227.4,0,0,118838.45,0.378466401273885,84434.45,7347,5579,0,0,1071,1318,99749.45,0.317673407643312 159 | 316000,0.991083838822675,87425.65,19592,5626,6952,227.4,0,0,119823.05,0.379186867088608,85120.85,7347,5626,0,0,1071,1318,100482.85,0.317983702531646 160 | 318000,0.991236491904057,88165.65,19716,5673,6996,227.4,0,0,120778.05,0.379805188679245,85780.85,7347,5673,0,0,1071,1318,101189.85,0.318207075471698 161 | 320000,0.991389144985438,88935.25,19840,5720,7040,227.4,0,0,121762.65,0.38050828125,86467.25,7347,5720,0,0,1071,1318,101923.25,0.31851015625 162 | 322000,0.99154179806682,89704.85,19964,5767,7084,227.4,0,0,122747.25,0.381202639751553,87153.65,7347,5767,0,0,1071,1318,102656.65,0.318809472049689 163 | 324000,0.991694451148201,90474.45,20088,5814,7128,227.4,0,0,123731.85,0.381888425925926,87840.05,7347,5814,0,0,1071,1318,103390.05,0.319105092592593 164 | 326000,0.991847104229582,91244.05,20212,5861,7172,227.4,0,0,124716.45,0.382565797546012,88526.45,7347,5861,0,0,1071,1318,104123.45,0.319397085889571 165 | 328000,0.991999757310964,91984.05,20336,5908,7216,227.4,0,0,125671.45,0.383144664634146,89186.45,7347,5908,0,0,1071,1318,104830.45,0.319605030487805 166 | 330000,0.992152410392345,92753.65,20460,5955,7260,227.4,0,0,126656.05,0.383806212121212,89872.85,7347,5955,0,0,1071,1318,105563.85,0.319890454545455 167 | 332000,0.992305063473726,93523.25,20584,6002,7304,227.4,0,0,127640.65,0.384459789156626,90559.25,7347,6002,0,0,1071,1318,106297.25,0.320172439759036 168 | 334000,0.992457716555108,94292.85,20708,6049,7348,227.4,0,0,128625.25,0.385105538922156,91245.65,7347,6049,0,0,1071,1318,107030.65,0.320451047904192 169 | 336000,0.992610369636489,95062.45,20832,6096,7392,227.4,0,0,129609.85,0.385743601190476,91932.05,7347,6096,0,0,1071,1318,107764.05,0.320726339285714 170 | 338000,0.992763022717871,95802.45,20956,6143,7436,227.4,0,0,130564.85,0.386286538461538,92592.05,7347,6143,0,0,1071,1318,108471.05,0.320920266272189 171 | 340000,0.992915675799252,96572.05,21080,6190,7480,227.4,0,0,131549.45,0.386910147058824,93278.45,7347,6190,0,0,1071,1318,109204.45,0.321189558823529 172 | 342000,0.993068328880634,97341.65,21204,6237,7524,227.4,0,0,132534.05,0.387526461988304,93964.85,7347,6237,0,0,1071,1318,109937.85,0.321455701754386 173 | 344000,0.993220981962015,98111.25,21328,6284,7568,227.4,0,0,133518.65,0.388135610465116,94651.25,7347,6284,0,0,1071,1318,110671.25,0.32171875 174 | 346000,0.993373635043396,98880.85,21452,6331,7612,227.4,0,0,134503.25,0.388737716763006,95337.65,7347,6331,0,0,1071,1318,111404.65,0.321978757225434 175 | 348000,0.993526288124778,99620.85,21576,6378,7656,227.4,0,0,135458.25,0.389247844827586,95997.65,7347,6378,0,0,1071,1318,112111.65,0.322159913793103 176 | 350000,0.993678941206159,100390.45,21700,6425,7700,227.4,0,0,136442.85,0.389836714285714,96684.05,7347,6425,0,0,1071,1318,112845.05,0.322414428571429 177 | 352000,0.993831594287541,101160.05,21824,6472,7744,227.4,0,0,137427.45,0.390418892045455,97370.45,7347,6472,0,0,1071,1318,113578.45,0.322666051136364 178 | 354000,0.993984247368922,101929.65,21948,6519,7788,227.4,0,0,138412.05,0.390994491525424,98056.85,7347,6519,0,0,1071,1318,114311.85,0.322914830508475 179 | 356000,0.994136900450303,102699.25,22072,6566,7832,227.4,0,0,139396.65,0.391563623595506,98743.25,7347,6566,0,0,1071,1318,115045.25,0.323160814606742 180 | 358000,0.994289553531685,103439.25,22196,6613,7876,227.4,0,0,140351.65,0.392043715083799,99403.25,7347,6613,0,0,1071,1318,115752.25,0.32333030726257 181 | 360000,0.994442206613066,104208.85,22320,6660,7920,227.4,0,0,141336.25,0.392600694444444,100089.65,7347,6660,0,0,1071,1318,116485.65,0.32357125 182 | 362000,0.994594859694447,104978.45,22444,6707,7964,227.4,0,0,142320.85,0.393151519337017,100776.05,7347,6707,0,0,1071,1318,117219.05,0.32380953038674 183 | 364000,0.994747512775829,105748.05,22568,6754,8008,227.4,0,0,143305.45,0.393696291208791,101462.45,7347,6754,0,0,1071,1318,117952.45,0.324045192307692 184 | 366000,0.99490016585721,106517.65,22692,6801,8052,227.4,0,0,144290.05,0.394235109289618,102148.85,7347,6801,0,0,1071,1318,118685.85,0.324278278688525 185 | 368000,0.995052818938592,107257.65,22816,6848,8096,227.4,0,0,145245.05,0.394687635869565,102808.85,7347,6848,0,0,1071,1318,119392.85,0.324437092391304 186 | 370000,0.995205472019973,108027.25,22940,6895,8140,227.4,0,0,146229.65,0.39521527027027,103495.25,7347,6895,0,0,1071,1318,120126.25,0.324665540540541 187 | 372000,0.995358125101354,108796.85,23064,6942,8184,227.4,0,0,147214.25,0.395737231182796,104181.65,7347,6942,0,0,1071,1318,120859.65,0.324891532258065 188 | 374000,0.995510778182736,109566.45,23188,6989,8228,227.4,0,0,148198.85,0.396253609625668,104868.05,7347,6989,0,0,1071,1318,121593.05,0.325115106951872 189 | 376000,0.995663431264117,110336.05,23312,7036,8272,227.4,0,0,149183.45,0.396764494680851,105554.45,7347,7036,0,0,1071,1318,122326.45,0.325336303191489 190 | 378000,0.995816084345499,111076.05,23436,7083,8316,227.4,0,0,150138.45,0.397191666666667,106214.45,7347,7083,0,0,1071,1318,123033.45,0.325485317460318 191 | 380000,0.99596873742688,111845.65,23560,7130,8360,227.4,0,0,151123.05,0.397692236842105,106900.85,7347,7130,0,0,1071,1318,123766.85,0.325702236842105 192 | 382000,0.996121390508261,112615.25,23684,7177,8404,227.4,0,0,152107.65,0.398187565445026,107587.25,7347,7177,0,0,1071,1318,124500.25,0.325916884816754 193 | 384000,0.996274043589643,113355.25,23808,7224,8448,227.4,0,0,153062.65,0.398600651041667,108247.25,7347,7224,0,0,1071,1318,125207.25,0.326060546875 194 | 386000,0.996426696671024,114095.25,23932,7271,8492,227.4,0,0,154017.65,0.399009455958549,108907.25,7347,7271,0,0,1071,1318,125914.25,0.326202720207254 195 | 388000,0.996579349752406,114835.25,24056,7318,8536,227.4,0,0,154972.65,0.399414046391753,109567.25,7347,7318,0,0,1071,1318,126621.25,0.326343427835052 196 | 390000,0.996732002833787,115575.25,24180,7365,8580,227.4,0,0,155927.65,0.399814487179487,110227.25,7347,7365,0,0,1071,1318,127328.25,0.326482692307692 197 | 392000,0.996884655915168,116315.25,24304,7412,8624,227.4,0,0,156882.65,0.400210841836735,110887.25,7347,7412,0,0,1071,1318,128035.25,0.326620535714286 198 | 394000,0.99703730899655,117055.25,24428,7459,8668,227.4,0,0,157837.65,0.400603172588832,111547.25,7347,7459,0,0,1071,1318,128742.25,0.326756979695431 199 | 396000,0.997189962077931,117795.25,24552,7506,8712,227.4,0,0,158792.65,0.40099154040404,112207.25,7347,7506,0,0,1071,1318,129449.25,0.326892045454545 200 | 398000,0.997342615159313,118535.25,24676,7553,8756,227.4,0,0,159747.65,0.401376005025126,112867.25,7347,7553,0,0,1071,1318,130156.25,0.327025753768844 201 | 4e+05,0.997495268240694,119275.25,24800,7600,8800,227.4,0,0,160702.65,0.401756625,113527.25,7347,7600,0,0,1071,1318,130863.25,0.327158125 202 | 402000,0.997647921322075,120015.25,24924,7647,8844,227.4,0,0,161657.65,0.402133457711443,114187.25,7347,7647,0,0,1071,1318,131570.25,0.327289179104478 203 | --------------------------------------------------------------------------------