cmfproperty
for?The property tax is the single largest source of locally generated revenue for American local governments. Cities, counties, school districts, and special districts raise roughly $500 billion per year in property taxes according to The Urban Institute.
Property taxes are supposed to be a flat tax where everyone pays the same rate regardless of how much their home is worth. In practice, property taxes are regressive in almost every single county in America, according to a recent nationwide analysis by the Center for Municipal Finance which analyzed 40 million property sales. For an individual homeowner, understanding if their home was assessed fairly is relatively difficult. A homeowner only knows what their home is assessed for and only knows how accurately their home was assessed if it sells in a given year.
cmfproperty
provides the necessary tools for the public, assessors, and public interest groups to evaluate the effectiveness of assessment systems by removing subject-matter and technical barriers and producing automated contextualized reports. These reports analyze the assessor’s own data using industry standards and visualizations designed to illustrate inequities and package the information in an easy to use format.
cmfproperty
?First, check out the article on preprocessing which outlines data requirements and examples. In order to analyze assessments, data is required to have at least three columns: Sale Year, Sale Price, and Assessed Value.
head(cmfproperty::example_data)
#> PIN SALE_YEAR SALE_PRICE ASSESSED_VALUE
#> 1 17273100931118 2015 53000 33860
#> 2 18013090421010 2018 80000 60390
#> 3 12111190201042 2018 118000 108300
#> 4 13093160601015 2017 125500 87200
#> 5 14322110150000 2018 3705000 3670740
#> 6 27021200080000 2016 345000 267280
After gathering data in this form, we have to identify the three required columns (sales, assessments, and sale year) for the package using cmfproperty::reformat_data
.
ratios <-
cmfproperty::reformat_data(
data = cmfproperty::example_data,
sale_col = "SALE_PRICE",
assessment_col = "ASSESSED_VALUE",
sale_year_col = "SALE_YEAR",
)
#> [1] "Filtered out non-arm's length transactions"
#> [1] "Inflation adjusted to 2019"
head(as.data.frame(ratios))
#> PIN SALE_YEAR SALE_PRICE ASSESSED_VALUE TAX_YEAR RATIO
#> 1 17273100931118 2015 53000 33860 2015 0.6388679
#> 2 18013090421010 2018 80000 60390 2018 0.7548750
#> 3 12111190201042 2018 118000 108300 2018 0.9177966
#> 4 13093160601015 2017 125500 87200 2017 0.6948207
#> 5 14322110150000 2018 3705000 3670740 2018 0.9907530
#> 6 27021200080000 2016 345000 267280 2016 0.7747246
#> arms_length_transaction SALE_PRICE_ADJ ASSESSED_VALUE_ADJ
#> 1 1 59209.48 37827.04
#> 2 1 82313.03 62136.05
#> 3 1 121411.71 111431.26
#> 4 1 132854.54 92310.09
#> 5 1 3812122.01 3776871.45
#> 6 1 376080.37 291358.73
We denote data processed by cmfproperty::reformat_data
as ratios
throughout the documentation. ratios
includes the additional calculated fields needed to complete the study.
There’s one more step to get the automated report:
cmfproperty::make_report(ratios,
jurisdiction_name = "Cook County, Illinois")
The report will be saved in your working directory or a specific directory can be provided.
cmfproperty::make_report(ratios,
jurisdiction_name = "Cook County, Illinois",
output_dir = "~/Desktop/")
Check out an example report here.
Check out our methods and information on figures in addition to function-level documentation. The core unit of analysis that we use (and is standard) is the Sales Ratio. A sales ratio is a calculated ratio between the sale price and assessed value at the time of sale for an individual property. Properties should be assessed at their fair market value which is defined as the sale price when sold between two unrelated parties in an arm’s length transaction. We then apply the standard method to determine if a sale is arm’s length from the International Association of Assessing Officers.
If you would like to use our package to make your own report, simply take ratios
and create stats
.
stats <- cmfproperty::calc_iaao_stats(ratios)
head(stats)
#> N COD COD_SE PRD PRD_SE PRB PRB_SE q1_ratio median_ratio
#> 1 51879 19.2009 6.1946 1.0578 0.0079 -0.0514 0.0012 0.7758364 0.9093448
#> 2 62852 20.0905 6.6369 1.0798 0.0219 -0.0462 0.0011 0.7705720 0.9001375
#> 3 65961 20.0706 5.8239 1.0600 0.0074 -0.0269 0.0011 0.7428108 0.8732099
#> 4 65298 18.4733 5.1744 1.0308 0.0077 0.0133 0.0010 0.7470336 0.8856039
#> 5 62041 18.0105 5.5011 1.0143 0.0097 0.0098 0.0010 0.7681042 0.9035000
#> q3_ratio q1_sale median_sale q3_sale q1_assessed_value median_assessed_value
#> 1 1.057180 148000 230000 375000 136670.0 213430
#> 2 1.060422 148000 229900 365000 133940.0 209150
#> 3 1.031267 155000 235000 365000 136960.0 209380
#> 4 1.021504 159642 239900 370000 132382.5 210645
#> 5 1.036399 164900 245000 372000 140220.0 217690
#> q3_assessed_value Year
#> 1 331235.0 2015
#> 2 321720.0 2016
#> 3 316300.0 2017
#> 4 331257.5 2018
#> 5 336480.0 2019
With stats
and ratios
, you have the necessary tools for all the forms of analysis we present. For example,
output <- diagnostic_plots(stats,
ratios,
min_reporting_yr = 2015,
max_reporting_yr = 2019)
output[[1]]
We also present a series of diagnostic graphs to evaluate data quality, especially unexpected year-to-year changes. The diagnostic section can optionally be included as an appendix to the report as follows.
cmfproperty::make_report(ratios,
jurisdiction_name = "Cook County, Illinois Diagnostic",
output_dir = "~/../Documents/GitHub/cmf-uchicago.github.io/",
diagnostic = TRUE)
Check out a report on the example data with a diagnostic section here.