From 40405a7335a5887b967b00a24abf6a033ef15bb9 Mon Sep 17 00:00:00 2001 From: Eric Langowski <33432469+erhla@users.noreply.github.com> Date: Thu, 18 Jan 2024 14:39:11 -0600 Subject: [PATCH 01/21] 2022 Data Update (#23) * 2022 has different column name for levy_plus_loss "levy+loss" * update agency make sheet explicit, update across syntax, add 2022 column names * Update cpihistory.pdf * Switching to pdftools Pretty sure this is the same but didn't want to use noncran tabulizer * from press release * remove tabulizer * add 2022 * add excel conversions * update 2006 to 2012 to excel versions * add 2022 tax code * sample 2022 bills * update with pdftools * lint /style --- data-raw/agency/Agency Rate Report 2022.xlsx | 3 + data-raw/agency/agency.R | 20 +- data-raw/agency/tif_agency_names.csv | 4 +- data-raw/cpi/cpi.R | 26 ++- data-raw/cpi/cpihistory.pdf | Bin 130 -> 130 bytes data-raw/eq_factor/eq_factor.csv | 4 +- .../2022_200_04261010740000.pdf | Bin 0 -> 130 bytes .../2022_202_28244220220000.pdf | Bin 0 -> 130 bytes .../2022_203_19063120380000.pdf | Bin 0 -> 130 bytes .../2022_204_02171060120000.pdf | Bin 0 -> 130 bytes .../2022_205_10252080490000.pdf | Bin 0 -> 130 bytes .../2022_211_14333001380000.pdf | Bin 0 -> 130 bytes .../2022_299_14052110241207.pdf | Bin 0 -> 130 bytes .../2022_299_23222000451009.pdf | Bin 0 -> 130 bytes .../2022_593_08261020260000.pdf | Bin 0 -> 130 bytes .../sample_tax_bills_detail.R | 50 +++-- .../sample_tax_bills_detail.csv | 4 +- .../tax_code/2022 Tax Code Agency Rate.xlsx | 3 + data-raw/tax_code/tax_code.R | 9 + .../2022 TIF Agency Distribution Report.xlsx | 3 + data-raw/tif/main/2006 Cook TIF Summary.xlsx | 3 + data-raw/tif/main/2007 Cook TIF Summary.xlsx | 3 + data-raw/tif/main/2008 Cook TIF Summary.xlsx | 3 + data-raw/tif/main/2009 Cook TIF Summary.xlsx | 3 + data-raw/tif/main/2010 Cook TIF Summary.xlsx | 3 + data-raw/tif/main/2011 Cook TIF Summary.xlsx | 3 + data-raw/tif/main/2012 Cook TIF Summary.xlsx | 3 + .../main/2022 Cook County TIF Summary.xlsx | 3 + data-raw/tif/tif.R | 197 ++++++++---------- 29 files changed, 202 insertions(+), 145 deletions(-) create mode 100644 data-raw/agency/Agency Rate Report 2022.xlsx create mode 100644 data-raw/sample_tax_bills/2022_200_04261010740000.pdf create mode 100644 data-raw/sample_tax_bills/2022_202_28244220220000.pdf create mode 100644 data-raw/sample_tax_bills/2022_203_19063120380000.pdf create mode 100644 data-raw/sample_tax_bills/2022_204_02171060120000.pdf create mode 100644 data-raw/sample_tax_bills/2022_205_10252080490000.pdf create mode 100644 data-raw/sample_tax_bills/2022_211_14333001380000.pdf create mode 100644 data-raw/sample_tax_bills/2022_299_14052110241207.pdf create mode 100644 data-raw/sample_tax_bills/2022_299_23222000451009.pdf create mode 100644 data-raw/sample_tax_bills/2022_593_08261020260000.pdf create mode 100644 data-raw/tax_code/2022 Tax Code Agency Rate.xlsx create mode 100644 data-raw/tif/distribution/2022 TIF Agency Distribution Report.xlsx create mode 100644 data-raw/tif/main/2006 Cook TIF Summary.xlsx create mode 100644 data-raw/tif/main/2007 Cook TIF Summary.xlsx create mode 100644 data-raw/tif/main/2008 Cook TIF Summary.xlsx create mode 100644 data-raw/tif/main/2009 Cook TIF Summary.xlsx create mode 100644 data-raw/tif/main/2010 Cook TIF Summary.xlsx create mode 100644 data-raw/tif/main/2011 Cook TIF Summary.xlsx create mode 100644 data-raw/tif/main/2012 Cook TIF Summary.xlsx create mode 100644 data-raw/tif/main/2022 Cook County TIF Summary.xlsx diff --git a/data-raw/agency/Agency Rate Report 2022.xlsx b/data-raw/agency/Agency Rate Report 2022.xlsx new file mode 100644 index 0000000..1b7a766 --- /dev/null +++ b/data-raw/agency/Agency Rate Report 2022.xlsx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5eacae6ce69cf64f7903ffbe248a198422c1905614d0e14fa20467a867fe6a3 +size 882953 diff --git a/data-raw/agency/agency.R b/data-raw/agency/agency.R index 0a00dc6..1033450 100644 --- a/data-raw/agency/agency.R +++ b/data-raw/agency/agency.R @@ -43,9 +43,6 @@ file_names <- list.files( ) - - - # agency_fund ------------------------------------------------------------------ # Load the detail sheet from each agency file. This includes the levy and rate @@ -64,7 +61,7 @@ agency_fund <- map_dfr(file_names, function(file) { "loss", "loss_percent", "fund_loss" ))) %>% rename_with(~"levy_plus_loss", any_of(c( - "levy_and_loss", "fund_levy_plus_loss" + "levy_and_loss", "fund_levy_plus_loss", "levy_loss" ))) %>% rename_with(~"rate_ceiling", any_of(c( "ceiling", "rate_ceiling", "fund_rate_ceiling" @@ -189,7 +186,7 @@ arrow::write_parquet( # EAV, final extension, and much more agency <- map_dfr(file_names, function(file) { message("Reading: ", file) - readxl::read_xlsx(file) %>% + readxl::read_xlsx(file, sheet = 1) %>% set_names(snakecase::to_snake_case(names(.))) %>% mutate( across( @@ -235,9 +232,12 @@ agency <- map_dfr(file_names, function(file) { "reduction_percent", "reduction_factor", "clerk_reduction_factor" ))) %>% rename_with(~"total_non_cap_ext", any_of(c( - "total_non_cap_ext", "final_non_cap_ext" + "total_non_cap_ext", "final_non_cap_ext", "total_non_cap_extension" + ))) %>% + rename_with(~"total_ext", any_of(c( + "total_ext", "final_ext", + "grand_total_ext" ))) %>% - rename_with(~"total_ext", any_of(c("total_ext", "final_ext"))) %>% # Select, order, and rename columns select( year, @@ -296,20 +296,20 @@ agency <- map_dfr(file_names, function(file) { arrange(year, agency_num) %>% # Coerce columns to expected types mutate( - across(c(year), as.character), + across(c(year), ~ as.character(.x)), across( c( lim_numerator, lim_denominator, prior_eav:cty_total_eav, total_levy, total_max_levy, total_reduced_levy, total_final_levy ), - as.integer64 + ~ as.integer64(.x) ), across( c( lim_rate, pct_burden, total_prelim_rate, total_final_rate, reduction_pct, total_non_cap_ext, total_ext ), - as.double + ~ as.double(.x) ) ) diff --git a/data-raw/agency/tif_agency_names.csv b/data-raw/agency/tif_agency_names.csv index 8a8edae..74f6c15 100644 --- a/data-raw/agency/tif_agency_names.csv +++ b/data-raw/agency/tif_agency_names.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fcbcf43f2a66232e2f309f75339ed5057da12c33d27692d270b37df776d9f46d -size 26934 +oid sha256:6ca59da53a3bdc008f0b514829aa6717f9fa1d99d421509a6754078d8b329f61 +size 27439 diff --git a/data-raw/cpi/cpi.R b/data-raw/cpi/cpi.R index 29246c0..7976ea8 100644 --- a/data-raw/cpi/cpi.R +++ b/data-raw/cpi/cpi.R @@ -1,7 +1,7 @@ library(arrow) library(dplyr) library(miniUI) -library(tabulizer) +library(pdftools) library(tidyr) library(stringr) @@ -14,27 +14,33 @@ row_to_names <- function(df) { # The goal of this script is to create a data frame of Consumer Price Indices # CPI-U used by PTELL to calculate/cap property tax extensions # We can load the historical CPIs from a PDF provided by the State of Illinois +# https://tax.illinois.gov/content/dam/soi/en/web/tax/localgovernments/property/documents/cpihistory.pdf # Paths for local raw data storage and remote storage on S3 remote_bucket <- Sys.getenv("S3_REMOTE_BUCKET") remote_path <- file.path(remote_bucket, "cpi", "part-0.parquet") -# Extract the table only (no headers), then manually assign header -cpi_ext <- extract_areas(file = "data-raw/cpi/cpihistory.pdf")[[1]] -cpi <- as_tibble(cpi_ext[, c(1, 2, 4, 5, 6)]) -cpi <- setNames(cpi, c("year", "cpi", "ptell_cook", "comments", "levy_year")) +cpi <- pdftools::pdf_text(pdf = "data-raw/cpi/cpihistory.pdf") %>% + str_extract(., regex("1991.*", dotall = TRUE)) %>% + str_remove_all(., "\\(5 % for Cook\\)") %>% + str_split(., "\n") %>% + unlist() %>% + tibble(vals = `.`) %>% + mutate(vals = str_squish(vals)) %>% + separate_wider_delim( + col = vals, + names = c("year", "cpi", "pct", "ptell_cook", "levy_year", "year_paid"), + delim = " ", too_few = "align_start", too_many = "drop" + ) -# Merge Cook rate into main column cpi <- cpi %>% mutate( across(c(year, levy_year), as.character), across(c(cpi), as.numeric), - across(c(ptell_cook, comments), readr::parse_number), - ptell_cook = ifelse(!is.na(comments), comments, ptell_cook), + across(c(ptell_cook), readr::parse_number), ptell_cook = ptell_cook / 100 ) %>% - select(-comments) %>% - filter(year != "1991") %>% + filter(year != "1991", year != "", year != "CPI") %>% arrange(year) # Write to S3 diff --git a/data-raw/cpi/cpihistory.pdf b/data-raw/cpi/cpihistory.pdf index 3eed185beedda5b84f53656a22235c39920e9adf..e6fedfd1fb28335a0ff457152f957ac5905a5367 100644 GIT binary patch delta 83 zcmV~$u@QhU2nEoy%@mFxkS}Bhmq-ZQS=(7=0!Q|}wXN+tFNf5o=p57LkdZi?FsxZ1 d(o|DeSvZn{01}&2nF00g=~ABijlDq?^}zO8^OX)^?Um;K=&=x6@89pBOz@zz2n_j^u0hLW7OD fBDx9a3?m|MWpD{Y(0^FdT4fpK`+DL~sHXV?)z}tK diff --git a/data-raw/eq_factor/eq_factor.csv b/data-raw/eq_factor/eq_factor.csv index d810123..21e3600 100644 --- a/data-raw/eq_factor/eq_factor.csv +++ b/data-raw/eq_factor/eq_factor.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3013b8ac0e6ddae2eeb73a446c5d323904507e4f2b0562aa6acf4e034aeb82b -size 832 +oid sha256:2a27cbc30f2e5281f69006fda8c56bac0d6d7cebd577100e9452c77e379816b1 +size 850 diff --git a/data-raw/sample_tax_bills/2022_200_04261010740000.pdf b/data-raw/sample_tax_bills/2022_200_04261010740000.pdf new file mode 100644 index 0000000000000000000000000000000000000000..336ca65ba6330f3f5b3e5ebac1119ba6bbcbbff2 GIT binary patch literal 130 zcmWN?OA^8$3;@tQr{Dq>NJ)g=hEEV?R63^Z!qe;9yo*0F=3DpU*kv>3F^=1_$@0IS zc`5T{WanZor{<_ydIF>^RqtI07=T@_IU>=TeN5nLBHMuP6gjpMaw}M{<=A`xVsy-j N0hNp|Ygnx%^#k;jCLin|}0g?(cDjie1@bvmN@8Y+N`O^J757~^lkMs7}W%=Jf zb!qcy2#~l5d(U046o6G-p z@>0gj%w3APoEp9A*|JAk#bS(}At#CnD+^VCK MtJ%Mzy-#;kKh#tv+5i9m literal 0 HcmV?d00001 diff --git a/data-raw/sample_tax_bills/2022_204_02171060120000.pdf b/data-raw/sample_tax_bills/2022_204_02171060120000.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8eccf17e6a62520c2bc379f3533fce2be886b37f GIT binary patch literal 130 zcmWN?OA^8$3;@u5Pr(H&B*?F~36KgiDjh?+@bvmN@8Xa2@m6ilLpH4+ecqnCtpD4Y z*D_vO4leqFW%R0~5jwx!ImhB51Z#6d2Smk2cE;Ci0#ZsGGB7fc^8|Z^5MALUjjPyhe` literal 0 HcmV?d00001 diff --git a/data-raw/sample_tax_bills/2022_205_10252080490000.pdf b/data-raw/sample_tax_bills/2022_205_10252080490000.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f16c5ffdc01412c8b79d0759ba8e73b3346c9a20 GIT binary patch literal 130 zcmWN?OA^8$3;@u5Pr(H&A%QUTHhhH{m5#wKJiWfnyXsrUe5tQ4W&i*H literal 0 HcmV?d00001 diff --git a/data-raw/sample_tax_bills/2022_211_14333001380000.pdf b/data-raw/sample_tax_bills/2022_211_14333001380000.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6aedebc30ecbd6ce7496def3fc9d3a74795407db GIT binary patch literal 130 zcmWm3K@P$o5J1sAr{Dq>n8EjsBHwh@buQzPu@TIJ^KEVZO&tCO5OXsJ?dDl zwohJYf2wgXsndwP7dcu2hZ_M|49M26CMF0LI8}E^SuGpyG5i;5aLhn8$5A8*x;W1pMWkAB>qb*}&0 z$*YW)o_i5}!7_SQvn3?A5gA~}g@e0;1tyUUCOYGhF{g^5Ml$SE^1)TM;L)-nAu(P` Nlx6mBQHa6D0R{YK0dO|dGM;#v(Lw?@^ahG zyzJwx_@G@~MvPu0w+)!5CFhCuiyiQ%rI>E&9DhoDk;Gne7*LiukxOKykuMJoQG2PzHW~?xBu-E zw=|w=o+YUZ#OPVh#%SzeVn)BSp<-gd%vEO!nkzsh0t}vPa$YCm5)*sO770U!Jp==; NIx+jVNYvo1_yOcUCk+4q literal 0 HcmV?d00001 diff --git a/data-raw/sample_tax_bills/sample_tax_bills_detail.R b/data-raw/sample_tax_bills/sample_tax_bills_detail.R index e4d9d53..f026d9d 100644 --- a/data-raw/sample_tax_bills/sample_tax_bills_detail.R +++ b/data-raw/sample_tax_bills/sample_tax_bills_detail.R @@ -1,6 +1,6 @@ library(dplyr) library(tidyr) -library(tabulizer) +library(pdftools) library(miniUI) library(stringr) library(purrr) @@ -25,19 +25,43 @@ row_to_names <- function(df) { # Different tax bills can have different table sizes depending on the number of -# taxing district. As such, the table bottom boundary will be different for each -# bill. Here we manually specify the area of table using an interactive widget +# taxing district. extract_tax_bill <- function(file) { base_file <- basename(file) - - # Scan table into memory - tbl <- tabulizer::extract_areas(file = file, pages = 1)[[1]] %>% - as_tibble() %>% - row_to_names() %>% - set_names( - c("agency_name", "final_tax", "rate", "percent", "pension", "prev_tax") + tbl <- pdf_text(file)[[1]] %>% + str_extract(., regex("MISCELLANEOUS TAXES.*", dotall = TRUE)) %>% + str_split(., "\n") %>% + unlist() %>% + tibble(vals = `.`) %>% + mutate(vals = str_replace_all(vals, "[:space:]{2,}", "\t")) %>% + separate_wider_delim( + col = vals, + names = c( + "agency_name", "final_tax", "rate", "percent", + "pension", "prev_tax" + ), + delim = "\t", too_few = "align_start", too_many = "drop" + ) %>% + mutate( + agency_name = str_squish(agency_name), + flag = is.na(prev_tax), + prev_tax = if_else(flag, + pension, + prev_tax + ), + pension = if_else(flag, + NA, + pension + ) + ) %>% + select(-flag) %>% + filter( + agency_name != "", + !str_detect( + agency_name, + "TAXES|Assess|Property|EAV|Local Tax|Total Tax|Do not|Equalizer|cookcountyclerk.com" + ) ) - # Create a list with metadata for output out <- list( year = str_sub(base_file, 1, 4), @@ -91,8 +115,8 @@ bills_df <- bills_df %>% # Round numeric values to nearest hundredth bills_df <- bills_df %>% mutate( - across(c(final_tax, percent, pension, prev_tax), round, 2), - across(c(rate), round, 3), + across(c(final_tax, percent, pension, prev_tax), ~ round(.x, 2)), + across(c(rate), ~ round(.x, 3)), ) # Write detail results to file for safekeeping diff --git a/data-raw/sample_tax_bills/sample_tax_bills_detail.csv b/data-raw/sample_tax_bills/sample_tax_bills_detail.csv index e89b6dc..5165fc7 100644 --- a/data-raw/sample_tax_bills/sample_tax_bills_detail.csv +++ b/data-raw/sample_tax_bills/sample_tax_bills_detail.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5f5a9f5fea3b6a41cfac65661a95d4bb0699c17e0da67d25792739db5d93022c -size 47317 +oid sha256:9214efd6a6b050bb1778f7a2be742091c79e58acd33b58456c2b21b13aaeae03 +size 54474 diff --git a/data-raw/tax_code/2022 Tax Code Agency Rate.xlsx b/data-raw/tax_code/2022 Tax Code Agency Rate.xlsx new file mode 100644 index 0000000..9b55b61 --- /dev/null +++ b/data-raw/tax_code/2022 Tax Code Agency Rate.xlsx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eee13315554b2c096e6513c2ff13e0cb178b9c46473f2ddd414bd705f52102bb +size 1892319 diff --git a/data-raw/tax_code/tax_code.R b/data-raw/tax_code/tax_code.R index e9dd268..562ea02 100644 --- a/data-raw/tax_code/tax_code.R +++ b/data-raw/tax_code/tax_code.R @@ -23,6 +23,7 @@ file_names <- list.files( # Load each file and cleanup columns, then combine into single df tax_code <- map_dfr(file_names, function(file) { # Extract year from file name + print(file) year_ext <- str_extract(file, "\\d{4}") # Load file based on extension @@ -39,6 +40,14 @@ tax_code <- map_dfr(file_names, function(file) { ~ str_replace(.x, "taxcode", "tax_code"), starts_with("taxcode") ) %>% + rename_with( + ~ str_replace(.x, "ag_rate", "agency_rate"), + starts_with("ag_rate") + ) %>% + rename_with( + ~ str_replace(.x, "code_rate", "tax_code_rate"), + starts_with("code_rate") + ) %>% mutate( year = as.character(year_ext), agency_rate = as.numeric(agency_rate), diff --git a/data-raw/tif/distribution/2022 TIF Agency Distribution Report.xlsx b/data-raw/tif/distribution/2022 TIF Agency Distribution Report.xlsx new file mode 100644 index 0000000..a6e75f2 --- /dev/null +++ b/data-raw/tif/distribution/2022 TIF Agency Distribution Report.xlsx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a60312f8c7a924bc88cb6728930027e6e512c89b1f811fe8964d5ea2f3d6cc3 +size 170449 diff --git a/data-raw/tif/main/2006 Cook TIF Summary.xlsx b/data-raw/tif/main/2006 Cook TIF Summary.xlsx new file mode 100644 index 0000000..37855c0 --- /dev/null +++ b/data-raw/tif/main/2006 Cook TIF Summary.xlsx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5007d3ce62da6d13adcb3cead8f89067589f10cdce5706730dd636a4e9ccf65 +size 49296 diff --git a/data-raw/tif/main/2007 Cook TIF Summary.xlsx b/data-raw/tif/main/2007 Cook TIF Summary.xlsx new file mode 100644 index 0000000..77ac46e --- /dev/null +++ b/data-raw/tif/main/2007 Cook TIF Summary.xlsx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1e5ec9fd252ef30b61dd3188cd4ab8746c088414a2b1f55c4f37cef89aaa225 +size 49870 diff --git a/data-raw/tif/main/2008 Cook TIF Summary.xlsx b/data-raw/tif/main/2008 Cook TIF Summary.xlsx new file mode 100644 index 0000000..b8e7f2c --- /dev/null +++ b/data-raw/tif/main/2008 Cook TIF Summary.xlsx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:524888448457d4fba43d003017c4113edc2716a869a305e1c69ec0a2995a95cf +size 51560 diff --git a/data-raw/tif/main/2009 Cook TIF Summary.xlsx b/data-raw/tif/main/2009 Cook TIF Summary.xlsx new file mode 100644 index 0000000..d95b6cf --- /dev/null +++ b/data-raw/tif/main/2009 Cook TIF Summary.xlsx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31369a4ada238a90beb50495772e1a81ed490932ea0c8b2bfc963a041b9d6cbf +size 51684 diff --git a/data-raw/tif/main/2010 Cook TIF Summary.xlsx b/data-raw/tif/main/2010 Cook TIF Summary.xlsx new file mode 100644 index 0000000..83d8792 --- /dev/null +++ b/data-raw/tif/main/2010 Cook TIF Summary.xlsx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d28ee538a87cdefeed16e7ca173e5639c3cfa68f775e8fb825f4bb9265eb4bbb +size 51203 diff --git a/data-raw/tif/main/2011 Cook TIF Summary.xlsx b/data-raw/tif/main/2011 Cook TIF Summary.xlsx new file mode 100644 index 0000000..5982abd --- /dev/null +++ b/data-raw/tif/main/2011 Cook TIF Summary.xlsx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2456c372a5e6d6cc678c981bf35f9eba00d0c53fafc5984778603b0af57a19a0 +size 50826 diff --git a/data-raw/tif/main/2012 Cook TIF Summary.xlsx b/data-raw/tif/main/2012 Cook TIF Summary.xlsx new file mode 100644 index 0000000..2ddf610 --- /dev/null +++ b/data-raw/tif/main/2012 Cook TIF Summary.xlsx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9861e8c3b13d71cfe60395e1f295063f699f0c4cd914e2bc82cd404d281d6db8 +size 52824 diff --git a/data-raw/tif/main/2022 Cook County TIF Summary.xlsx b/data-raw/tif/main/2022 Cook County TIF Summary.xlsx new file mode 100644 index 0000000..186f0a2 --- /dev/null +++ b/data-raw/tif/main/2022 Cook County TIF Summary.xlsx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5bfe861c1e1dd5a15c0398c40aed22023379fa114876186d530d46426e157641 +size 45095 diff --git a/data-raw/tif/tif.R b/data-raw/tif/tif.R index a4b3cac..a1a242e 100644 --- a/data-raw/tif/tif.R +++ b/data-raw/tif/tif.R @@ -7,7 +7,6 @@ library(purrr) library(readxl) library(snakecase) library(stringr) -library(tabulizer) library(tidyr) calc_mode <- function(x) { @@ -76,113 +75,93 @@ tif_main_xls <- map_dfr(summ_file_names_xls, function(file) { df <- readxl::read_xlsx(file) } - df %>% - mutate(year = year_ext) %>% - set_names(snakecase::to_snake_case(names(.))) %>% - rename_with(~ str_replace(.x, str_c(year_ext, "_"), "curr_year_")) %>% - rename_with(~ str_replace(.x, str_c(year_ext - 1, "_"), "prev_year_")) %>% - mutate( - cancelled_this_year = - year == str_extract(new_cancelled, "\\d{4}") & - str_detect(tolower(new_cancelled), "cancel"), - across(c(cancelled_this_year), ~ replace_na(.x, FALSE)), - across(c(curr_year_revenue, prev_year_revenue), ~ replace_na(.x, 0)), - agency = str_pad(agency, 9, "left", "0") - ) %>% - select( - year, - agency_num = agency, tif_name, prev_year_revenue, - curr_year_revenue, first_year, cancelled_this_year, - ) -}) - - -## PDF files ----- - -# Get summary report PDFs -summ_file_names_pdf <- list.files( - path = "data-raw/tif/main", - pattern = "*Summary\\.pdf", - full.names = TRUE -) - -tif_main_pdf <- map_dfr(summ_file_names_pdf, function(file) { - message("Reading: ", file) - year_ext <- as.integer(str_extract(file, "\\d{4}")) - - # Extract tables from PDFs. Some tables get an extra 3rd column which we can - # drop - tables <- extract_tables(file) %>% - map(function(x) if (ncol(x) > 6) x[, c(1:2, 4:7)] else x) %>% - .[lapply(., nrow) > 1] - - do.call(rbind, tables) %>% - as_tibble() %>% - set_names(c( - "agency_num", "tif_name", "first_year", - "curr_year_revenue", "prev_year_revenue", "pct_diff" - )) %>% - filter(agency_num != "AGENCY") %>% - na_if("-") %>% - na_if("") %>% - mutate( - year = year_ext, - agency_num = str_pad( - str_squish(str_trim(str_remove_all(agency_num, "-"))), - 9, - "left", - "0" - ), - cancelled_this_year = - year == str_extract(tif_name, "\\d{4}"), - tif_name = - str_trim(str_squish(str_remove(tif_name, "City of|Village of"))), - # Kludge for bad OCR/table extraction for certain cells - agency_num = case_when( - str_detect(tif_name, "Country Club Hills - 175th") & year == 2008 ~ - "030240501", - str_detect(tif_name, "Thornton - Downtown") & year == 2009 ~ - "031260501", - str_detect(tif_name, "Evanston - Dempster / Dodge") & year == 2012 ~ - "030380506", - str_detect(tif_name, "Homewood - East CBD") & year == 2012 ~ - "030600505", - str_detect(tif_name, "East Dundee") & year %in% 2012 ~ - "030320500", - str_detect(agency_num, "Homewood East CBD") & year == 2012 ~ - "030600505", - TRUE ~ agency_num - ), - first_year = ifelse( - tif_name == "2011" & agency_num == "030600505", - 2011, - first_year + # modify legacy pdf conversions to excel + if (between(year_ext, 2006, 2012)) { + df %>% + set_names(c( + "agency_num", "tif_name", "first_year", + "curr_year_revenue", "prev_year_revenue", "pct_diff" + )) %>% + filter(agency_num != "AGENCY") %>% + mutate(across(where(is.character), ~ na_if(., "-"))) %>% + mutate(across(where(is.character), ~ na_if(., " "))) %>% + mutate( + year = year_ext, + agency_num = str_pad( + str_squish(str_trim(str_remove_all(agency_num, "-"))), + 9, + "left", + "0" + ), + cancelled_this_year = + year == str_extract(tif_name, "\\d{4}"), + tif_name = + str_trim(str_squish(str_remove(tif_name, "City of|Village of"))), + # Kludge for bad OCR/table extraction for certain cells + agency_num = case_when( + str_detect(tif_name, "Country Club Hills - 175th") & year == 2008 ~ + "030240501", + str_detect(tif_name, "Thornton - Downtown") & year == 2009 ~ + "031260501", + str_detect(tif_name, "Evanston - Dempster / Dodge") & year == 2012 ~ + "030380506", + str_detect(tif_name, "Homewood - East CBD") & year == 2012 ~ + "030600505", + str_detect(tif_name, "East Dundee") & year %in% 2012 ~ + "030320500", + str_detect(agency_num, "Homewood East CBD") & year == 2012 ~ + "030600505", + TRUE ~ agency_num + ), + first_year = ifelse( + tif_name == "2011" & agency_num == "030600505", + 2011, + first_year + ) + ) %>% + filter(!is.na(agency_num)) %>% + mutate( + tif_name = str_remove_all(tif_name, "\\ *Cancel.*"), + tif_name = str_remove_all(tif_name, "\\ *CANCEL.*"), + tif_name = str_remove_all(tif_name, "\\ *New.*"), + tif_name = str_squish(str_trim(tif_name)), + cancelled_this_year = replace_na(cancelled_this_year, FALSE), + across( + c("first_year", "curr_year_revenue", "prev_year_revenue"), + ~ replace_na(readr::parse_number(.x), 0) + ) + ) %>% + select( + year, agency_num, tif_name, prev_year_revenue, + curr_year_revenue, first_year, cancelled_this_year ) - ) %>% - filter(!is.na(agency_num)) %>% - mutate( - tif_name = str_remove_all(tif_name, "\\ *Cancel.*"), - tif_name = str_remove_all(tif_name, "\\ *CANCEL.*"), - tif_name = str_remove_all(tif_name, "\\ *New.*"), - tif_name = str_squish(str_trim(tif_name)), - cancelled_this_year = replace_na(cancelled_this_year, FALSE), - across( - c("first_year", "curr_year_revenue", "prev_year_revenue"), - ~ replace_na(readr::parse_number(.x), 0) + } else { + df %>% + mutate(year = year_ext) %>% + set_names(snakecase::to_snake_case(names(.))) %>% + rename_with(~ str_replace(.x, str_c(year_ext, "_"), "curr_year_")) %>% + rename_with(~ str_replace(.x, str_c(year_ext - 1, "_"), "prev_year_")) %>% + mutate( + cancelled_this_year = + year == str_extract(new_cancelled, "\\d{4}") & + str_detect(tolower(new_cancelled), "cancel"), + across(c(cancelled_this_year), ~ replace_na(.x, FALSE)), + across(c(curr_year_revenue, prev_year_revenue), ~ replace_na(.x, 0)), + agency = str_pad(agency, 9, "left", "0") + ) %>% + select( + year, + agency_num = agency, tif_name, prev_year_revenue, + curr_year_revenue, first_year, cancelled_this_year, ) - ) %>% - select( - year, agency_num, tif_name, prev_year_revenue, - curr_year_revenue, first_year, cancelled_this_year - ) + } }) -# Combine Excel and PDF outputs into since data frame -tif_main <- bind_rows( - tif_main_pdf, - tif_main_xls -) %>% - filter(!is.na(tif_name)) %>% +tif_main <- tif_main_xls %>% + filter( + !is.na(tif_name), agency_num != "City of Chicago", + agency_num != "Suburban Total" + ) %>% # Manual fixes for misread values mutate( agency_num = ifelse( @@ -232,6 +211,14 @@ tif_main <- bind_rows( first_year = ifelse( agency_num == "030600504" & year == 2011, 2011, first_year + ), + agency_num = if_else(tif_name == "Melrsoe Park - Lake Street Corridor", + "030770509", + agency_num + ), + agency_num = if_else(tif_name == "Melrose Park - Joyce Bros. Storage", + "030770501", + agency_num ) ) %>% filter(!(agency_num == "030330500" & first_year == 2012)) %>% @@ -263,8 +250,6 @@ arrow::write_parquet( ) - - # tif_distribution ------------------------------------------------------------- ## Excel files ----- From fd42117cc1c8afa20992c493b7e2c35a5dca85c3 Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Thu, 18 Jan 2024 20:42:52 +0000 Subject: [PATCH 02/21] Fix spacing --- data-raw/agency/agency.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data-raw/agency/agency.R b/data-raw/agency/agency.R index 1033450..d7a856e 100644 --- a/data-raw/agency/agency.R +++ b/data-raw/agency/agency.R @@ -43,6 +43,8 @@ file_names <- list.files( ) + + # agency_fund ------------------------------------------------------------------ # Load the detail sheet from each agency file. This includes the levy and rate From c7bf08ff2e75c2bbaaa5bb182f4e69ca51a76697 Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Thu, 18 Jan 2024 20:45:25 +0000 Subject: [PATCH 03/21] Update deprecated across() call --- data-raw/agency/agency.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data-raw/agency/agency.R b/data-raw/agency/agency.R index d7a856e..45d5ff7 100644 --- a/data-raw/agency/agency.R +++ b/data-raw/agency/agency.R @@ -283,7 +283,7 @@ agency <- map_dfr(file_names, function(file) { 0, cty_cook_eav ), - across(starts_with("cty_"), replace_na, 0), + across(starts_with("cty_"), ~ replace_na(.x, 0)), # Make all percentages decimals across( c(pct_burden, reduction_pct), From ff09025ddb196e82b8beebb0039a1df8c47aabfb Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Thu, 18 Jan 2024 20:46:54 +0000 Subject: [PATCH 04/21] Replace tabulizer with pdftools dependency --- DESCRIPTION | 5 ++--- data-raw/cpi/cpi.R | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 8a9cae4..9c80f9e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -38,6 +38,7 @@ Suggests: lintr, odbc, openxlsx, + pdftools, pkgdown, prettymapr, purrr, @@ -49,7 +50,6 @@ Suggests: sf, snakecase, stringr, - tabulizer, testthat, tidyr, units, @@ -57,7 +57,6 @@ Suggests: Depends: R (>= 2.10) Remotes: - paleolimbot/geoarrow, - ropensci/tabulizer + paleolimbot/geoarrow Config/Requires_DB_Version: 2021.0.4 Config/Wants_DB_Version: 2021.0.4 diff --git a/data-raw/cpi/cpi.R b/data-raw/cpi/cpi.R index 7976ea8..01b550d 100644 --- a/data-raw/cpi/cpi.R +++ b/data-raw/cpi/cpi.R @@ -14,7 +14,7 @@ row_to_names <- function(df) { # The goal of this script is to create a data frame of Consumer Price Indices # CPI-U used by PTELL to calculate/cap property tax extensions # We can load the historical CPIs from a PDF provided by the State of Illinois -# https://tax.illinois.gov/content/dam/soi/en/web/tax/localgovernments/property/documents/cpihistory.pdf +# https://tax.illinois.gov/content/dam/soi/en/web/tax/localgovernments/property/documents/cpihistory.pdf # nolint # Paths for local raw data storage and remote storage on S3 remote_bucket <- Sys.getenv("S3_REMOTE_BUCKET") From 96c28bdd7a78536205fc77b2ef58fcf44cc6a119 Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Thu, 18 Jan 2024 21:09:10 +0000 Subject: [PATCH 05/21] Add bill detail data object --- data/sample_tax_bills_detail.rda | Bin 10926 -> 11933 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/sample_tax_bills_detail.rda b/data/sample_tax_bills_detail.rda index 413c396c165c40c883150f0f0f3fda542aa4132b..b193cb1c086a8894c3fa6221d2fffaebe08103df 100644 GIT binary patch literal 11933 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 literal 10926 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 From e9dd0b750a55d1ff2924923afcc4adf9441375df Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Thu, 18 Jan 2024 21:36:32 +0000 Subject: [PATCH 06/21] Add sample tax bills summary data --- .../sample_tax_bills_summary.csv | 4 ++-- data/sample_tax_bills_summary.rda | Bin 1964 -> 2250 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data-raw/sample_tax_bills/sample_tax_bills_summary.csv b/data-raw/sample_tax_bills/sample_tax_bills_summary.csv index b6c95a0..1feb39e 100644 --- a/data-raw/sample_tax_bills/sample_tax_bills_summary.csv +++ b/data-raw/sample_tax_bills/sample_tax_bills_summary.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eae93e3cfc8d5396e424f4bccf11468f685e16ece56487c03a73c374e52bfda6 -size 4948 +oid sha256:426a0db657b219904d3e76983363350297e710e58c25d5ea4b7b3b78986f8b96 +size 5975 diff --git a/data/sample_tax_bills_summary.rda b/data/sample_tax_bills_summary.rda index c9c2851f1a86d607f1f12370f4435bed69fbc037..8bbdd38156df5c34adbf631c81b8045eaebcd788 100644 GIT binary patch literal 2250 zcmV;*2sQUYT4*^jL0KkKSs%7S0HrBTPxDKT#S000w|E z0MGyc0000o0BC45000000001J0000rJVYeY6&L^j0000000000000000Wbgn00000 zCIJ`#fh1~-)ENdNMkYa~nlPGaiKa|VF&HL8%4z8yfF>q`005YnjSPka(WVm!G|7Su z2AMG!0E0$Brhw6*pvcfP8UO%kqeg>6O#n0i88pxgBSSy{13+Q`4FCW%0AvF|5=erN zB4TY!O;giqnr#WD#R2K4^$j#+27#xj27r2=pa99B&;h264@tDt0j7gTs5YS5Kn)p` z^$h@IP9EN(90ZrN$z5HY%;d2>v4Rn7A(~~7^C5;vhBLzmW=T*J%YwCcfUUqvX8`1Y z8Il+V1f#-dBs>`%eTOBw+c_Xmp^l<0`%s4iE-=s19HCuih2zFyDrhN@1J-N z_I(I8t;)N`I%1|@$I*bMy=)4%%3kd11VkK2Km>7C#S=k-<;IS{FsU?&AR=6YQjw-g z2}vfIq>!hdeK0*`P=h0G8suw5s7%NsiPDNPiNzdhT3;fJ8qAXsXogy~Yhh;~n6w2Q zUT${9vS|n&wsy!l_Ldl{>_+aAHmyn|Qrgv}3nC3RDry)cI%Hr(ATZV@h&WTx5eX+- zyihU)<+QT4qTFuYeGpRg-a)Y}bjgh&m>H7Sb_mMiY2t*b)t_~E%z~>^C99)! z+%I|T1OyyN07MI@U;qMU3ppq~p%J7>D>6p_(6Ga+umS?juIqUdcLcJ?NutuF!=rFY zcv8_xqZA~YE|S3las!YW+G^`K5@f}oQ49!yBtaLei>a`}#oW^FsM3)NRLVgew^|u1cFMnAS143C&&Tu&mXmKxoYZM;0+} z8<`Phaw_7Z3QdLzif>qSgfe3vsinnICv95xIGW~79fo1dS&rtT02;A$q_z}AD9A*M zh6W5&VNpumD4fgD-uVS^66ywQgbiQ|Wwcfr)Wdntuz?cIhWsp3;b;a$0hu5BA{k075t*D7L7}R!ygSf_A<)A)umsaPI?nQq(jXE_AiIV`3bKgEp`_4g zr!WS5;1M7A6vD#PX$S@q5L!aY4H+~;!2P2LzrdV@ zAqb3v;go%d7u#r5(wlX}QH`$I=0h)Nj$!cVoFtbLB@w8?lonSai;D&%@x2=`qj9p0F1h!`4fyni%EdxU0-! z6=X=E2aqx!0}vcLJZG|d!jz?L6bFnK!-B|SGR%?)hY;ZHR(XbMgn6K_p-nMKtjIHC z?aTs>ZIvL9voF;C zktRye`r=9f1K8e|dU5?a;Y}<#dl-#!q^KSwT7i+q{aM;QL~Q-ny6-CfnE^4**j#Z) zHZA|9aMSFaPfYd^v;1cVA~<5^!r-?V@KiI^Zc(hNJy_Xt>Q%u7mTuIp8NztqONdyr z{QXzzS!1-X=RrTiy0GwY%Y4QN*bKI2H}hFsCB&`KeG~=W3XgwO;T|>u{Vp8s3#A|r zA%X*WC0>Bvvj?EuMjxhOr^Ga2N(-Ld3BzAXGFrJR$|Z%-wb z0SK*L3D)xtN&j&#MUq;R4)O=a1Yg#f`||pTc%5cpEDD$ew1jj>krLlBC9ED%M1eOR YI_$%~;K)P0XL-fkkxmpO2knr#0F2PuNdN!< literal 1964 zcmb7;Ydq5n1AzZCW@BobOEVp|nPK7Q@;~L0)9e;I+sKwsYL=sMN+Fb2HP@1+VX`f~ zXJ!ed43&$J)BElH`aaM1=l9T}#eQBvQDlD9O_w8cfNArQ zyM9V(r?!v9how9FqtL|1CRzaWOF2&6x<)k z1s4G^FtoUm&ywJ9f%FlWG;pIjXcmXer2^vHYM2xR7IF6K|JsY?*2yFmAhJMe0ayUT zLC0(@0GI@b8v?w6z8aRw8^i$s2;2Y@YAor-C`e7V>~@tJqQ;56paeBA1RzxajA{$^ z4zpO_^DqgvKnm)`LdnR&9gs^x1E2+9S_=$Q#UKDt1OEdE{2#Rv21%b#B~y$f+LwtD zxx}~yiC8RxI@iXDL0lkJj8%GnKUBgbI9u>`H5ZCgoX9?>?eNJ=OwnFa?dbbBshqH? zk0)GjgM$x*;dm-tc!7y|dZqQ4*#xO5*bI)@O%Kr)j&rGupz8KZkdQAOG$*=eP4~f< zsjX$X4q-X+kvI`!H&bIy6W%Pv>&{Ge^_CFa)|Rq7fycA*u)LV$@M)3`s3-K}(W>~{ zU$#^x+ON!hd;dW5a^k7ag4rpmYsAF?0+}$mj(5 zrho)h;wo@Zy2p&?vdCL=^KWQl#kRG&x?Kg^*Y&0pb7mORl)T>!>|I{x(UE*(z2zaB zi0$bYgI?`md|Hb0)VzVoY*O9Zhr^XbU0|t7dYL1ML+M{#ScQWWHCJb#O4NH+dAJd0 zTXwVaY0*#N?4k|F0mw-#&N*h-nD&Jdpy54#t;*Q4!WsuxWsdVqR9yetBWD`hmW>6Q6ld&&|Ec4M zlI}(-PrM|@IyWJ;*rViHb3#yJu%PRf(@tPfqp;<-$c1`~IV|;hH^mK_@8aEz8tXE} z$LEOAjGsJnYw#K&DtVtHHq$@L?Ggu0Zph`ERt9@kd&#ckr83R!!`YkBwtCR471V^k@mA}L_i3Z)G{k4&}LH+jHd8-=>JM8$na8vR%)}-MrF(8VEaK&r3ogia5 z`kd#-@0jTP_LfgnVY1mYNLrj#Aag%Ee9E=N%|&>_M4R~`ESjZzV=_u7pu+6fA$_~Fe%zJZCvck@tJd{pVZL z3hxqP*!8E94%(&qZmF#|ewTbY;zQ>|O6sin$se1l5y!Bwl5dzA z*=WgDb}3zr(OK0rIsvxSVKRV)TpzE)^Gj8DEf%D?5wdr-)4~b`3Pjn(Qotr03sq!D*ylh From 5317ba4a14b238c3bf4c063a70e489b0be1410ca Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Thu, 18 Jan 2024 22:24:30 +0000 Subject: [PATCH 07/21] Fix tax bill agency name matching Give priority to certain names on bills in the detail output and add names for TY2022 --- .../sample_tax_bills/agency_name_match.csv | 4 ++-- .../sample_tax_bills_detail.R | 8 ++++++-- .../sample_tax_bills_detail.csv | 4 ++-- data/sample_tax_bills_detail.rda | Bin 11933 -> 12617 bytes 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/data-raw/sample_tax_bills/agency_name_match.csv b/data-raw/sample_tax_bills/agency_name_match.csv index 59327c1..6e5425f 100644 --- a/data-raw/sample_tax_bills/agency_name_match.csv +++ b/data-raw/sample_tax_bills/agency_name_match.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d76e4471b3e6b34eb199abe6e2db6887609b451361bb45d68f918172f69dc749 -size 7254 +oid sha256:71405da084f2e0f2e43eeeed38df92d170683bfcfbf540102d392148e03104d4 +size 8945 diff --git a/data-raw/sample_tax_bills/sample_tax_bills_detail.R b/data-raw/sample_tax_bills/sample_tax_bills_detail.R index f026d9d..2566ba2 100644 --- a/data-raw/sample_tax_bills/sample_tax_bills_detail.R +++ b/data-raw/sample_tax_bills/sample_tax_bills_detail.R @@ -59,7 +59,10 @@ extract_tax_bill <- function(file) { agency_name != "", !str_detect( agency_name, - "TAXES|Assess|Property|EAV|Local Tax|Total Tax|Do not|Equalizer|cookcountyclerk.com" + paste0( + "TAXES|Assess|Property|EAV|Local Tax|", + "Total Tax|Do not|Equalizer|cookcountyclerk.com" + ) ) ) # Create a list with metadata for output @@ -109,7 +112,8 @@ bills_df <- bills_df %>% group_by(pin, year, agency_num) %>% mutate(across(final_tax:prev_tax, sum)) %>% select(-cook) %>% - filter(!is.na(agency_num), row_number() == 1) %>% + filter(!is.na(agency_num), name_priority == 1) %>% + select(-name_priority) %>% ungroup() # Round numeric values to nearest hundredth diff --git a/data-raw/sample_tax_bills/sample_tax_bills_detail.csv b/data-raw/sample_tax_bills/sample_tax_bills_detail.csv index 5165fc7..0ab28d0 100644 --- a/data-raw/sample_tax_bills/sample_tax_bills_detail.csv +++ b/data-raw/sample_tax_bills/sample_tax_bills_detail.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9214efd6a6b050bb1778f7a2be742091c79e58acd33b58456c2b21b13aaeae03 -size 54474 +oid sha256:db21c8a42ffa4197f645ecce23c82f8d1be7ee7b50646ed513b2f80ee85e647b +size 57270 diff --git a/data/sample_tax_bills_detail.rda b/data/sample_tax_bills_detail.rda index b193cb1c086a8894c3fa6221d2fffaebe08103df..8935633cbf78f4823fe607c3be037d1210ce3573 100644 GIT binary patch literal 12617 zcmV-PF}BV^T4*^jL0KkKS=RkHX8>%DfB*mg|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0 z|NsC0|Nr1M+Q9qdhtOqi%Hydm?E2?bnKpH(@ld4q68qb&-~a#s1poyA05f0;prbkf zUH||901r9`(;r&;!LZT`nvoT~Vt}VmB~iNf4-;k%h4guS>}x^LaZpe?9V??-yMXCH zl0*7uRBcT%Z%~-hAE`9W5CcZiVtP!QQzIkP$OA^184pt?BRx|f zJxopNm?i|!H2qQPJqXZXnrWw~$)+P}X`s_UZAK$NB194iN0Jj$YI;GC0003!O`#fM zW|{_xfu?{o00A^(M95%95cB|yOaMjzCIBV?13*j!WMC!)N+5s;6H0!kil3>VX`z)o zH9aFjewv<;Jtj$~l5B>F;FD@(8feJcO⪼9*Fdwpf;g|^n)O2p{9)wNP3wxGBE%& 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 literal 11933 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 From 4d8cc62bd702869e3b160b884202700e1b64c721 Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Thu, 18 Jan 2024 23:29:44 +0000 Subject: [PATCH 08/21] Add Athena pull to fill missing AVs --- DESCRIPTION | 1 + data-raw/pin/pin.R | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 9c80f9e..b543c80 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -36,6 +36,7 @@ Suggests: httr, knitr, lintr, + noctua, odbc, openxlsx, pdftools, diff --git a/data-raw/pin/pin.R b/data-raw/pin/pin.R index f67cbf4..a8303bb 100644 --- a/data-raw/pin/pin.R +++ b/data-raw/pin/pin.R @@ -2,6 +2,7 @@ library(arrow) library(DBI) library(dplyr) library(geoarrow) +library(noctua) library(odbc) library(sf) library(tidyr) @@ -27,6 +28,10 @@ ccaodata <- dbConnect( .connection_string = Sys.getenv("DB_CONFIG_CCAODATA") ) +# Establish a connection the Data Department's Athena data warehouse. We'll use +# values from here to fill in any missing values from the legacy system +ccaoathena <- dbConnect(noctua::athena()) + # Pull AV and class from the Clerk and HEAD tables, giving preference to values # from the Clerk table in case of mismatch (except for property class). # These tables are pulled from the AS/400 and will be pulled from iasWorld @@ -82,6 +87,25 @@ pin <- dbGetQuery( tax_bill_total = tidyr::replace_na(tax_bill_total, 0) ) +# Pull AVs from Athena to fill in any missingness from the legacy system +pin_athena <- dbGetQuery( + ccaoathena, + " + SELECT DISTINCT + pin, + year, + mailed_tot, + certified_tot, + board_tot + FROM default.vw_pin_value + WHERE year >= '2006' + " +) %>% + mutate( + across(c(year, pin), as.character), + across(c(ends_with("_tot")), as.integer) + ) + pin_fill <- pin %>% # There are a few (less than 100) rows with Clerk AVs split for the same PIN. # Sum to get 1 record per PIN, then keep the record with the highest AV @@ -89,6 +113,12 @@ pin_fill <- pin %>% mutate(av_clerk = sum(av_clerk)) %>% ungroup() %>% distinct(year, pin, .keep_all = TRUE) %>% + left_join(pin_athena, by = c("year", "pin")) %>% + mutate( + av_board = ifelse(is.na(av_board), board_tot, av_board), + av_certified = ifelse(is.na(av_certified), certified_tot, av_certified), + av_mailed = ifelse(is.na(av_mailed), mailed_tot, av_mailed) + ) %>% # A few (less than 500) values are missing from the mailed assessment stage # AV column. We can replace any missing mailed value with certified value # from the same year. Only 2 board/certified values are missing, and both are @@ -97,7 +127,8 @@ pin_fill <- pin %>% av_board = ifelse(is.na(av_board), 0L, av_board), av_certified = ifelse(is.na(av_certified), 0L, av_certified), av_mailed = ifelse(is.na(av_mailed), av_certified, av_mailed) - ) + ) %>% + select(-ends_with("_tot")) # Write to S3 arrow::write_dataset( From 119a774ef82e36bba5c148af59084cb763425574 Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Fri, 19 Jan 2024 03:16:48 +0000 Subject: [PATCH 09/21] Drop unneeded CPI columns --- data-raw/cpi/cpi.R | 1 + 1 file changed, 1 insertion(+) diff --git a/data-raw/cpi/cpi.R b/data-raw/cpi/cpi.R index 01b550d..98289f7 100644 --- a/data-raw/cpi/cpi.R +++ b/data-raw/cpi/cpi.R @@ -41,6 +41,7 @@ cpi <- cpi %>% ptell_cook = ptell_cook / 100 ) %>% filter(year != "1991", year != "", year != "CPI") %>% + select(-pct, -year_paid) %>% arrange(year) # Write to S3 From 663a87f2e313bb9a25b11a6acc8bcc272f46b37c Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Fri, 19 Jan 2024 03:17:18 +0000 Subject: [PATCH 10/21] Increment DB version year --- DESCRIPTION | 2 +- data-raw/create_db.R | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index b543c80..9eb6499 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -60,4 +60,4 @@ Depends: Remotes: paleolimbot/geoarrow Config/Requires_DB_Version: 2021.0.4 -Config/Wants_DB_Version: 2021.0.4 +Config/Wants_DB_Version: 2022.0.0 diff --git a/data-raw/create_db.R b/data-raw/create_db.R index af73e37..dc0c1eb 100644 --- a/data-raw/create_db.R +++ b/data-raw/create_db.R @@ -37,7 +37,7 @@ db_send_queries <- function(conn, sql) { # changes. This is checked against Config/Requires_DB_Version in the DESCRIPTION # file via check_db_version(). Schema is: # "MAX_YEAR_OF_DATA.MAJOR_VERSION.MINOR_VERSION" -db_version <- "2021.0.4" +db_version <- "2022.0.0" # Set the package version required to use this database. This is checked against # Version in the DESCRIPTION file. Basically, we have a two-way check so that From eb9476b1fb09ae40efec017e91c5f170ceda2303 Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Fri, 19 Jan 2024 05:00:55 +0000 Subject: [PATCH 11/21] Revert using xlsx TIF summary files --- data-raw/tif/main/2006 Cook TIF Summary.xlsx | 3 - data-raw/tif/main/2007 Cook TIF Summary.xlsx | 3 - data-raw/tif/main/2008 Cook TIF Summary.xlsx | 3 - data-raw/tif/main/2009 Cook TIF Summary.xlsx | 3 - data-raw/tif/main/2010 Cook TIF Summary.xlsx | 3 - data-raw/tif/main/2011 Cook TIF Summary.xlsx | 3 - data-raw/tif/main/2012 Cook TIF Summary.xlsx | 3 - data-raw/tif/tif.R | 197 ++++++++++--------- 8 files changed, 106 insertions(+), 112 deletions(-) delete mode 100644 data-raw/tif/main/2006 Cook TIF Summary.xlsx delete mode 100644 data-raw/tif/main/2007 Cook TIF Summary.xlsx delete mode 100644 data-raw/tif/main/2008 Cook TIF Summary.xlsx delete mode 100644 data-raw/tif/main/2009 Cook TIF Summary.xlsx delete mode 100644 data-raw/tif/main/2010 Cook TIF Summary.xlsx delete mode 100644 data-raw/tif/main/2011 Cook TIF Summary.xlsx delete mode 100644 data-raw/tif/main/2012 Cook TIF Summary.xlsx diff --git a/data-raw/tif/main/2006 Cook TIF Summary.xlsx b/data-raw/tif/main/2006 Cook TIF Summary.xlsx deleted file mode 100644 index 37855c0..0000000 --- a/data-raw/tif/main/2006 Cook TIF Summary.xlsx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f5007d3ce62da6d13adcb3cead8f89067589f10cdce5706730dd636a4e9ccf65 -size 49296 diff --git a/data-raw/tif/main/2007 Cook TIF Summary.xlsx b/data-raw/tif/main/2007 Cook TIF Summary.xlsx deleted file mode 100644 index 77ac46e..0000000 --- a/data-raw/tif/main/2007 Cook TIF Summary.xlsx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d1e5ec9fd252ef30b61dd3188cd4ab8746c088414a2b1f55c4f37cef89aaa225 -size 49870 diff --git a/data-raw/tif/main/2008 Cook TIF Summary.xlsx b/data-raw/tif/main/2008 Cook TIF Summary.xlsx deleted file mode 100644 index b8e7f2c..0000000 --- a/data-raw/tif/main/2008 Cook TIF Summary.xlsx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:524888448457d4fba43d003017c4113edc2716a869a305e1c69ec0a2995a95cf -size 51560 diff --git a/data-raw/tif/main/2009 Cook TIF Summary.xlsx b/data-raw/tif/main/2009 Cook TIF Summary.xlsx deleted file mode 100644 index d95b6cf..0000000 --- a/data-raw/tif/main/2009 Cook TIF Summary.xlsx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:31369a4ada238a90beb50495772e1a81ed490932ea0c8b2bfc963a041b9d6cbf -size 51684 diff --git a/data-raw/tif/main/2010 Cook TIF Summary.xlsx b/data-raw/tif/main/2010 Cook TIF Summary.xlsx deleted file mode 100644 index 83d8792..0000000 --- a/data-raw/tif/main/2010 Cook TIF Summary.xlsx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d28ee538a87cdefeed16e7ca173e5639c3cfa68f775e8fb825f4bb9265eb4bbb -size 51203 diff --git a/data-raw/tif/main/2011 Cook TIF Summary.xlsx b/data-raw/tif/main/2011 Cook TIF Summary.xlsx deleted file mode 100644 index 5982abd..0000000 --- a/data-raw/tif/main/2011 Cook TIF Summary.xlsx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2456c372a5e6d6cc678c981bf35f9eba00d0c53fafc5984778603b0af57a19a0 -size 50826 diff --git a/data-raw/tif/main/2012 Cook TIF Summary.xlsx b/data-raw/tif/main/2012 Cook TIF Summary.xlsx deleted file mode 100644 index 2ddf610..0000000 --- a/data-raw/tif/main/2012 Cook TIF Summary.xlsx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9861e8c3b13d71cfe60395e1f295063f699f0c4cd914e2bc82cd404d281d6db8 -size 52824 diff --git a/data-raw/tif/tif.R b/data-raw/tif/tif.R index a1a242e..47a28bd 100644 --- a/data-raw/tif/tif.R +++ b/data-raw/tif/tif.R @@ -7,6 +7,7 @@ library(purrr) library(readxl) library(snakecase) library(stringr) +library(tabulizer) library(tidyr) calc_mode <- function(x) { @@ -75,93 +76,113 @@ tif_main_xls <- map_dfr(summ_file_names_xls, function(file) { df <- readxl::read_xlsx(file) } - # modify legacy pdf conversions to excel - if (between(year_ext, 2006, 2012)) { - df %>% - set_names(c( - "agency_num", "tif_name", "first_year", - "curr_year_revenue", "prev_year_revenue", "pct_diff" - )) %>% - filter(agency_num != "AGENCY") %>% - mutate(across(where(is.character), ~ na_if(., "-"))) %>% - mutate(across(where(is.character), ~ na_if(., " "))) %>% - mutate( - year = year_ext, - agency_num = str_pad( - str_squish(str_trim(str_remove_all(agency_num, "-"))), - 9, - "left", - "0" - ), - cancelled_this_year = - year == str_extract(tif_name, "\\d{4}"), - tif_name = - str_trim(str_squish(str_remove(tif_name, "City of|Village of"))), - # Kludge for bad OCR/table extraction for certain cells - agency_num = case_when( - str_detect(tif_name, "Country Club Hills - 175th") & year == 2008 ~ - "030240501", - str_detect(tif_name, "Thornton - Downtown") & year == 2009 ~ - "031260501", - str_detect(tif_name, "Evanston - Dempster / Dodge") & year == 2012 ~ - "030380506", - str_detect(tif_name, "Homewood - East CBD") & year == 2012 ~ - "030600505", - str_detect(tif_name, "East Dundee") & year %in% 2012 ~ - "030320500", - str_detect(agency_num, "Homewood East CBD") & year == 2012 ~ - "030600505", - TRUE ~ agency_num - ), - first_year = ifelse( - tif_name == "2011" & agency_num == "030600505", - 2011, - first_year - ) - ) %>% - filter(!is.na(agency_num)) %>% - mutate( - tif_name = str_remove_all(tif_name, "\\ *Cancel.*"), - tif_name = str_remove_all(tif_name, "\\ *CANCEL.*"), - tif_name = str_remove_all(tif_name, "\\ *New.*"), - tif_name = str_squish(str_trim(tif_name)), - cancelled_this_year = replace_na(cancelled_this_year, FALSE), - across( - c("first_year", "curr_year_revenue", "prev_year_revenue"), - ~ replace_na(readr::parse_number(.x), 0) - ) - ) %>% - select( - year, agency_num, tif_name, prev_year_revenue, - curr_year_revenue, first_year, cancelled_this_year + df %>% + mutate(year = year_ext) %>% + set_names(snakecase::to_snake_case(names(.))) %>% + rename_with(~ str_replace(.x, str_c(year_ext, "_"), "curr_year_")) %>% + rename_with(~ str_replace(.x, str_c(year_ext - 1, "_"), "prev_year_")) %>% + mutate( + cancelled_this_year = + year == str_extract(new_cancelled, "\\d{4}") & + str_detect(tolower(new_cancelled), "cancel"), + across(c(cancelled_this_year), ~ replace_na(.x, FALSE)), + across(c(curr_year_revenue, prev_year_revenue), ~ replace_na(.x, 0)), + agency = str_pad(agency, 9, "left", "0") + ) %>% + select( + year, + agency_num = agency, tif_name, prev_year_revenue, + curr_year_revenue, first_year, cancelled_this_year, + ) +}) + + +## PDF files ----- + +# Get summary report PDFs +summ_file_names_pdf <- list.files( + path = "data-raw/tif/main", + pattern = "*Summary\\.pdf", + full.names = TRUE +) + +tif_main_pdf <- map_dfr(summ_file_names_pdf, function(file) { + message("Reading: ", file) + year_ext <- as.integer(str_extract(file, "\\d{4}")) + + # Extract tables from PDFs. Some tables get an extra 3rd column which we can + # drop + tables <- extract_tables(file) %>% + map(function(x) if (ncol(x) > 6) x[, c(1:2, 4:7)] else x) %>% + .[lapply(., nrow) > 1] + + do.call(rbind, tables) %>% + as_tibble() %>% + set_names(c( + "agency_num", "tif_name", "first_year", + "curr_year_revenue", "prev_year_revenue", "pct_diff" + )) %>% + filter(agency_num != "AGENCY") %>% + mutate(across(where(is.character), ~ na_if(.x, "-"))) %>% + mutate(across(where(is.character), ~ na_if(.x, ""))) %>% + mutate( + year = year_ext, + agency_num = str_pad( + str_squish(str_trim(str_remove_all(agency_num, "-"))), + 9, + "left", + "0" + ), + cancelled_this_year = + year == str_extract(tif_name, "\\d{4}"), + tif_name = + str_trim(str_squish(str_remove(tif_name, "City of|Village of"))), + # Kludge for bad OCR/table extraction for certain cells + agency_num = case_when( + str_detect(tif_name, "Country Club Hills - 175th") & year == 2008 ~ + "030240501", + str_detect(tif_name, "Thornton - Downtown") & year == 2009 ~ + "031260501", + str_detect(tif_name, "Evanston - Dempster / Dodge") & year == 2012 ~ + "030380506", + str_detect(tif_name, "Homewood - East CBD") & year == 2012 ~ + "030600505", + str_detect(tif_name, "East Dundee") & year %in% 2012 ~ + "030320500", + str_detect(agency_num, "Homewood East CBD") & year == 2012 ~ + "030600505", + TRUE ~ agency_num + ), + first_year = ifelse( + tif_name == "2011" & agency_num == "030600505", + 2011, + first_year ) - } else { - df %>% - mutate(year = year_ext) %>% - set_names(snakecase::to_snake_case(names(.))) %>% - rename_with(~ str_replace(.x, str_c(year_ext, "_"), "curr_year_")) %>% - rename_with(~ str_replace(.x, str_c(year_ext - 1, "_"), "prev_year_")) %>% - mutate( - cancelled_this_year = - year == str_extract(new_cancelled, "\\d{4}") & - str_detect(tolower(new_cancelled), "cancel"), - across(c(cancelled_this_year), ~ replace_na(.x, FALSE)), - across(c(curr_year_revenue, prev_year_revenue), ~ replace_na(.x, 0)), - agency = str_pad(agency, 9, "left", "0") - ) %>% - select( - year, - agency_num = agency, tif_name, prev_year_revenue, - curr_year_revenue, first_year, cancelled_this_year, + ) %>% + filter(!is.na(agency_num)) %>% + mutate( + tif_name = str_remove_all(tif_name, "\\ *Cancel.*"), + tif_name = str_remove_all(tif_name, "\\ *CANCEL.*"), + tif_name = str_remove_all(tif_name, "\\ *New.*"), + tif_name = str_squish(str_trim(tif_name)), + cancelled_this_year = replace_na(cancelled_this_year, FALSE), + across( + c("first_year", "curr_year_revenue", "prev_year_revenue"), + ~ replace_na(readr::parse_number(.x), 0) ) - } + ) %>% + select( + year, agency_num, tif_name, prev_year_revenue, + curr_year_revenue, first_year, cancelled_this_year + ) }) -tif_main <- tif_main_xls %>% - filter( - !is.na(tif_name), agency_num != "City of Chicago", - agency_num != "Suburban Total" - ) %>% +# Combine Excel and PDF outputs into since data frame +tif_main <- bind_rows( + tif_main_pdf, + tif_main_xls +) %>% + filter(!is.na(tif_name)) %>% # Manual fixes for misread values mutate( agency_num = ifelse( @@ -211,14 +232,6 @@ tif_main <- tif_main_xls %>% first_year = ifelse( agency_num == "030600504" & year == 2011, 2011, first_year - ), - agency_num = if_else(tif_name == "Melrsoe Park - Lake Street Corridor", - "030770509", - agency_num - ), - agency_num = if_else(tif_name == "Melrose Park - Joyce Bros. Storage", - "030770501", - agency_num ) ) %>% filter(!(agency_num == "030330500" & first_year == 2012)) %>% @@ -250,6 +263,8 @@ arrow::write_parquet( ) + + # tif_distribution ------------------------------------------------------------- ## Excel files ----- From 04c372a8fe4b47fddafb936417b7a0cf11e78e72 Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Fri, 19 Jan 2024 05:04:16 +0000 Subject: [PATCH 12/21] Re-add tabulizer dependency --- DESCRIPTION | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 9eb6499..84990f7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -51,6 +51,7 @@ Suggests: sf, snakecase, stringr, + tabulizer, testthat, tidyr, units, @@ -58,6 +59,7 @@ Suggests: Depends: R (>= 2.10) Remotes: - paleolimbot/geoarrow + paleolimbot/geoarrow, + ropensci/tabulizer Config/Requires_DB_Version: 2021.0.4 Config/Wants_DB_Version: 2022.0.0 From 7047555c9a51ec9df334b80430853aae9e64dc89 Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Fri, 19 Jan 2024 06:28:35 +0000 Subject: [PATCH 13/21] Update README for TY2022 --- README.Rmd | 4 +-- README.md | 50 +++++++++++++------------- man/figures/README-multi_year_4-1.png | Bin 23212 -> 22799 bytes 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/README.Rmd b/README.Rmd index 695d32f..71eb286 100644 --- a/README.Rmd +++ b/README.Rmd @@ -173,7 +173,7 @@ There are some minor differences between PTAXSIM and the real bill. The taxing d We can also look at a single property over multiple years, in this case broken out by taxing district. To do so, pass a vector of multiple years to the `year_vec` argument of `tax_bill()`: ```{r multi_year_1, message=FALSE, warning=FALSE} -multiple_years <- tax_bill(2010:2021, "14081020210000") +multiple_years <- tax_bill(2010:2022, "14081020210000") multiple_years ``` @@ -208,7 +208,7 @@ multiple_years_plot <- ggplot(data = multiple_years_summ) + annotate( "text", x = 2015.8, - y = 12500, + y = 11500, label = "RPM TIF enacted", hjust = 1 ) + diff --git a/README.md b/README.md index 954da5a..2f45315 100644 --- a/README.md +++ b/README.md @@ -37,13 +37,13 @@ Table of Contents > installation](#database-installation) for details. > > [**Link to PTAXSIM -> database**](https://ccao-data-public-us-east-1.s3.amazonaws.com/ptaxsim/ptaxsim-2021.0.4.db.bz2) -> (DB version: 2021.0.4; Last updated: 2023-04-28 23:40:05) +> database**](https://ccao-data-public-us-east-1.s3.amazonaws.com/ptaxsim/ptaxsim-2022.0.0.db.bz2) +> (DB version: 2022.0.0; Last updated: 2024-01-19 04:40:35) PTAXSIM is an R package/database to approximate Cook County property tax bills. It uses real assessment, exemption, TIF, and levy data to generate historic, line-item tax bills (broken out by taxing district) -for any property from 2006 to 2021. Given some careful assumptions and +for any property from 2006 to 2022. Given some careful assumptions and data manipulation, it can also provide hypothetical, but factually grounded, answers to questions such as: @@ -173,9 +173,9 @@ database: 1. Download the compressed database file from the CCAO’s public S3 bucket. [Link - here](https://ccao-data-public-us-east-1.s3.amazonaws.com/ptaxsim/ptaxsim-2021.0.4.db.bz2). + here](https://ccao-data-public-us-east-1.s3.amazonaws.com/ptaxsim/ptaxsim-2022.0.0.db.bz2). 2. (Optional) Rename the downloaded database file by removing the - version number, i.e. ptaxsim-2021.0.4.db.bz2 becomes + version number, i.e. ptaxsim-2022.0.0.db.bz2 becomes `ptaxsim.db.bz2`. 3. Decompress the downloaded database file. The file is compressed using [bzip2](https://sourceware.org/bzip2/). @@ -434,7 +434,7 @@ broken out by taxing district. To do so, pass a vector of multiple years to the `year_vec` argument of `tax_bill()`: ``` r -multiple_years <- tax_bill(2010:2021, "14081020210000") +multiple_years <- tax_bill(2010:2022, "14081020210000") multiple_years #> year pin class tax_code av eav agency_num #> 1: 2010 14081020210000 206 73001 69062 227905 010010000 @@ -443,11 +443,11 @@ multiple_years #> 4: 2010 14081020210000 206 73001 69062 227905 030210001 #> 5: 2010 14081020210000 206 73001 69062 227905 030210002 #> --- -#> 122: 2021 14081020210000 206 73105 70000 210189 043030000 -#> 123: 2021 14081020210000 206 73105 70000 210189 044060000 -#> 124: 2021 14081020210000 206 73105 70000 210189 050200000 -#> 125: 2021 14081020210000 206 73105 70000 210189 050200001 -#> 126: 2021 14081020210000 206 73105 70000 210189 080180000 +#> 133: 2022 14081020210000 206 73105 70000 204659 043030000 +#> 134: 2022 14081020210000 206 73105 70000 204659 044060000 +#> 135: 2022 14081020210000 206 73105 70000 204659 050200000 +#> 136: 2022 14081020210000 206 73105 70000 204659 050200001 +#> 137: 2022 14081020210000 206 73105 70000 204659 080180000 #> agency_name agency_major_type agency_minor_type #> 1: COUNTY OF COOK COOK COUNTY COOK #> 2: FOREST PRESERVE DISTRICT ... COOK COUNTY COOK @@ -455,11 +455,11 @@ multiple_years #> 4: CITY OF CHICAGO LIBRARY F... MUNICIPALITY/TOWNSHIP LIBRARY #> 5: CITY OF CHICAGO SCHOOL BL... MUNICIPALITY/TOWNSHIP MISC #> --- -#> 122: CHICAGO COMMUNITY COLLEGE... SCHOOL COMM COLL -#> 123: BOARD OF EDUCATION SCHOOL UNIFIED -#> 124: CHICAGO PARK DISTRICT MISCELLANEOUS PARK -#> 125: CHICAGO PARK DISTRICT AQU... MISCELLANEOUS BOND -#> 126: METRO WATER RECLAMATION D... MISCELLANEOUS WATER +#> 133: CHICAGO COMMUNITY COLLEGE... SCHOOL COMM COLL +#> 134: BOARD OF EDUCATION SCHOOL UNIFIED +#> 135: CHICAGO PARK DISTRICT MISCELLANEOUS PARK +#> 136: CHICAGO PARK DISTRICT AQU... MISCELLANEOUS BOND +#> 137: METRO WATER RECLAMATION D... MISCELLANEOUS WATER #> agency_tax_rate final_tax #> 1: 0.00423 964.04 #> 2: 0.00051 116.23 @@ -467,11 +467,11 @@ multiple_years #> 4: 0.00102 232.46 #> 5: 0.00116 264.37 #> --- -#> 122: 0.00145 225.36 -#> 123: 0.03517 4984.70 -#> 124: 0.00311 483.37 -#> 125: 0.00000 0.00 -#> 126: 0.00382 593.71 +#> 133: 0.00155 238.81 +#> 134: 0.03757 5313.22 +#> 135: 0.00323 497.64 +#> 136: 0.00000 0.00 +#> 137: 0.00374 576.22 ``` The `tax_bill()` function will automatically combine the years and PIN @@ -509,7 +509,7 @@ multiple_years_plot <- ggplot(data = multiple_years_summ) + annotate( "text", x = 2015.8, - y = 12500, + y = 11500, label = "RPM TIF enacted", hjust = 1 ) + @@ -863,15 +863,15 @@ erDiagram - Currently, the per-district tax calculations for properties in the Red-Purple Modernization (RPM) TIF are slightly flawed. However, the - total tax bill per PIN is still accurate. See issue [\#4](https://github.com/ccao-data/ptaxsim/issues/4) for + total tax bill per PIN is still accurate. See issue [\#11](#11) for more information. - Special Service Area (SSA) rates must be calculated manually when - creating counterfactual bills. See issue [\#3](https://github.com/ccao-data/ptaxsim/issues/3) for more + creating counterfactual bills. See issue [\#31](#31) for more information. - In rare instances, a TIF can have multiple `agency_num` identifiers (usually there’s only one per TIF). The `tif_crosswalk` table determines what the “main” `agency_num` is for each TIF and pulls the - name and TIF information using that identifier. See archived issue [\#39](https://gitlab.com/ccao-data-science---modeling/packages/ptaxsim/-/issues/39) + name and TIF information using that identifier. See issue [\#39](#39) for more information. - PTAXSIM is relatively memory-efficient and can calculate every district line-item for every tax bill for the last 15 years (roughly diff --git a/man/figures/README-multi_year_4-1.png b/man/figures/README-multi_year_4-1.png index 661159afd1f5aa9136045d65828474a50106b17a..68aa02d48fb34f646b64f09257dcc84bd713ce34 100644 GIT binary patch literal 22799 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®mvSay*slgDzZ(}b4vEUwNyInNu-HAoq+?-xh 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

n{s=AXRd=Vtu} zqe()G0-S9G3_2zhh`f%arGYHG45_NKwh!(M#S4%r^zA=-41wmdva-_B(n?|~6J^p& zNhe!rYc7F6D{b-C;031sKQA!BlV>0K+fIY(FC#BcL>(X%;t<3-hYj}S?4ZN{0pTt3 A&Hw-a From c8dfd6dd34d36c9ef6d58789ede9dc1b34fcf1bc Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Fri, 19 Jan 2024 06:31:10 +0000 Subject: [PATCH 14/21] Update unit tests for 2022 data --- tests/testthat/test-lookup.R | 2 +- tests/testthat/test-tax_bill.R | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test-lookup.R b/tests/testthat/test-lookup.R index 8054fcb..ed7d0fe 100644 --- a/tests/testthat/test-lookup.R +++ b/tests/testthat/test-lookup.R @@ -232,7 +232,7 @@ test_that("lookup values/data are correct", { ) expect_known_hash( lookup_agency(sum_df$year, sum_df$tax_code), - "b0b8d1fbca" + "c4d062201d" ) }) diff --git a/tests/testthat/test-tax_bill.R b/tests/testthat/test-tax_bill.R index a489c6d..47fb2d7 100644 --- a/tests/testthat/test-tax_bill.R +++ b/tests/testthat/test-tax_bill.R @@ -140,12 +140,12 @@ test_that("returned amount/output correct for all sample bills", { expect_equal( tax_bill(sum_dt$year, sum_dt$pin, simplify = FALSE) %>% nrow(), - 508 + 621 ) expect_equal( tax_bill(sum_dt$year, sum_dt$pin, simplify = TRUE) %>% nrow(), - 525 + 639 ) # District level tax amounts @@ -164,7 +164,13 @@ test_that("returned amount/output correct for all sample bills", { # Exclude certain PINs in the RPM TIF or with extremely high bills # Will run separate tests for these sum_dt_no_rpm <- sum_dt %>% - filter(!pin %in% c("14174100180000", "01363010130000")) + filter(!pin %in% c( + "14174100180000", + "01363010130000", + "10252080490000" + # TODO: This last PIN has an exemption on its 2022 bill but not in the + # 2022 clerk data. Seems like a new parcel, need to investigate further + )) test_that("all differences are less than $25", { expect_true( From 20b7fad5b8fa136d4cd1d5780cf7b64048360569 Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Fri, 19 Jan 2024 06:40:06 +0000 Subject: [PATCH 15/21] Drop exemption from tax bill summary table --- .../sample_tax_bills_summary.csv | 4 ++-- data/sample_tax_bills_summary.rda | Bin 2250 -> 2249 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data-raw/sample_tax_bills/sample_tax_bills_summary.csv b/data-raw/sample_tax_bills/sample_tax_bills_summary.csv index 1feb39e..b5560f0 100644 --- a/data-raw/sample_tax_bills/sample_tax_bills_summary.csv +++ b/data-raw/sample_tax_bills/sample_tax_bills_summary.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:426a0db657b219904d3e76983363350297e710e58c25d5ea4b7b3b78986f8b96 -size 5975 +oid sha256:58df45909edc638165005622d8e9eec435866f154efbe1519067906e59ce9c6e +size 5976 diff --git a/data/sample_tax_bills_summary.rda b/data/sample_tax_bills_summary.rda index 8bbdd38156df5c34adbf631c81b8045eaebcd788..b08335a7ffa07953f88b15e1d59b80ebda97c86c 100644 GIT binary patch literal 2249 zcmV;)2sZaZT4*^jL0KkKSs$ly-~b5xfB*mg|NZFc|MP#}`}M#7|M_#f@ACfr|98Lt zb*=xr-+$l;9|i97&e(gn00F%AfC5s3L`2m#r-d~1ngh~pMw$kOMrvr#10kX60ibBw zk4OfOO;1n8hR(9dW2A$Nuqf*C!$~k7ywL|nrVP0 z6951LVFn3_gvi0500A%n1YiIF1j&Tc05r%#2{l3L00000000000000P0000000000 z0000q01zaNQHU@IWYbKTCYTc=1Y%&B7yu&^&?b!6q$l zWl3H%v44YopUE7qo?xzG8|2tQp^Qa{;M)+|O2|<$rE7?Qt-wm00D?dbq%asIH)P18ps8#-DRd+>?~uec!RMUDB#G2oMg=1Y9y^ zcykukDwN(1>ajrcQrR0Y_Jvmu1=X zv=3W5d>q|4IHUF>dV;XD$!!-5Ee&Eu3i;Nqu7I>`pkx(83*)R9jU}=Y(v7@DBSBTc zqT$HV7F1AW*PrrfLkGDj*I<%J}2@dzJB;VXD|9NFcDueiM+D&`=F* z1`;(vhTWA#LI|~KV=y3+C1^s^G?GblZ3xk@NoQDvoM{5!w15L<#I?K#6&|YJQ%`fJ z1vwnU7O3;!6>D7_O!TOgn&t^8G-dw?B)3fAFrLpWd((EcIQ&SXLxnN%u*^Myg9RbK z$*uos;`uO<6D3&$2E;+4BN|~q49KKtNp9&r3*~JQC%|Nzrtg!P(vkPjglpS;G=d zS4&WVH-mUItkLN=5@f|-G8Yj7NP;a#iz%qOrR-YIL|LL0hQ ztqmYJPj%CDia4~xh(r*gOgM{FObHVF0E-YRXvqpV1=76;dm%8Ubt8;U1VrG5B5i$b zeS_a}fE*QPSUbpQ7homgqUcpJT9?q(UxgzJ0G?>}WpyTwoq=a85;!=)-wPQLRbnXd zL32$-$&}iV?Fe6le+8^4kvodmaKO_fv(#ic7Dut5xCd1(%`V|YGdT#6VBlQhg6amP zl8MP?ds^{JguMXFoG@s$%P@%sNI(!x z1DD8_3Xx|L=z`>%1Pvex<5;9Uru6vI@(HrNQtRe|%n>z6u*VHVbE7?L*xzI^1&F;2 zN-hY=lqv$oilWf=VjM%UhdGc0wp_J)N;XJ_UhY3nx_7ujB2?RhCW7!YTWoE4_ zmaJaRkx6IMi;0F(0;W{#=f>5<(0md?6Oe-Uiec*VztJxVqEfNC_L3q&Z>*|@6>!)B zVG>iMKG;^*9zuaJq~y|o!%PHefQ*rj5da|pW4R7(;s6pP*xe=B0vA*5#Ol zqzF8KVpunW5aS~@)CNyT;2V4buvY*YNcu3$8l+OOve^vUT2d^}ymHwEfwnl+oeUTV z%TIxUNP5UK427m)nG*eRDi(#S62ZI+Jnbbe^3s0ZY!$`0YDDBx0|pU+Z$1bYt3(u|Y+4qjNEQZ2F3sjF!CgHfv7*0>Q@N!{h16CQE)1;HIet?wfJ&>0 z>QIRzL}X-#B;q)=7=Jwvv=}Mh4ldmMlk+(04 zJbP4vd0u9fYN4jZ=2R9dCskAFj53yES4x3$S(U*wOpi2aB_&i7A*O}9lB6P5WkA8m zSrZZ#OD#o8PgDtr&r%Gx2os6-#(>xbhU~tYB(qeVtc2guT2oyn+ z(rH+qT;!w>MVvD&pd+PRfu5HWWjOPb$H4+j+?fjg>8DGnVLcNfpXq#zfDYieQpWtozO+8~U$0Tp|`O6wBns+B~$Mls{ZBIB6}cqk>opqyqC X6kpUx6HKlRKk;`YQ-uiu`ga}xi4?z2 literal 2250 zcmV;*2sQUYT4*^jL0KkKSs%7S0HrBTPxDKT#S000w|E z0MGyc0000o0BC45000000001J0000rJVYeY6&L^j0000000000000000Wbgn00000 zCIJ`#fh1~-)ENdNMkYa~nlPGaiKa|VF&HL8%4z8yfF>q`005YnjSPka(WVm!G|7Su z2AMG!0E0$Brhw6*pvcfP8UO%kqeg>6O#n0i88pxgBSSy{13+Q`4FCW%0AvF|5=erN zB4TY!O;giqnr#WD#R2K4^$j#+27#xj27r2=pa99B&;h264@tDt0j7gTs5YS5Kn)p` z^$h@IP9EN(90ZrN$z5HY%;d2>v4Rn7A(~~7^C5;vhBLzmW=T*J%YwCcfUUqvX8`1Y z8Il+V1f#-dBs>`%eTOBw+c_Xmp^l<0`%s4iE-=s19HCuih2zFyDrhN@1J-N z_I(I8t;)N`I%1|@$I*bMy=)4%%3kd11VkK2Km>7C#S=k-<;IS{FsU?&AR=6YQjw-g z2}vfIq>!hdeK0*`P=h0G8suw5s7%NsiPDNPiNzdhT3;fJ8qAXsXogy~Yhh;~n6w2Q zUT${9vS|n&wsy!l_Ldl{>_+aAHmyn|Qrgv}3nC3RDry)cI%Hr(ATZV@h&WTx5eX+- zyihU)<+QT4qTFuYeGpRg-a)Y}bjgh&m>H7Sb_mMiY2t*b)t_~E%z~>^C99)! z+%I|T1OyyN07MI@U;qMU3ppq~p%J7>D>6p_(6Ga+umS?juIqUdcLcJ?NutuF!=rFY zcv8_xqZA~YE|S3las!YW+G^`K5@f}oQ49!yBtaLei>a`}#oW^FsM3)NRLVgew^|u1cFMnAS143C&&Tu&mXmKxoYZM;0+} z8<`Phaw_7Z3QdLzif>qSgfe3vsinnICv95xIGW~79fo1dS&rtT02;A$q_z}AD9A*M zh6W5&VNpumD4fgD-uVS^66ywQgbiQ|Wwcfr)Wdntuz?cIhWsp3;b;a$0hu5BA{k075t*D7L7}R!ygSf_A<)A)umsaPI?nQq(jXE_AiIV`3bKgEp`_4g zr!WS5;1M7A6vD#PX$S@q5L!aY4H+~;!2P2LzrdV@ zAqb3v;go%d7u#r5(wlX}QH`$I=0h)Nj$!cVoFtbLB@w8?lonSai;D&%@x2=`qj9p0F1h!`4fyni%EdxU0-! z6=X=E2aqx!0}vcLJZG|d!jz?L6bFnK!-B|SGR%?)hY;ZHR(XbMgn6K_p-nMKtjIHC z?aTs>ZIvL9voF;C zktRye`r=9f1K8e|dU5?a;Y}<#dl-#!q^KSwT7i+q{aM;QL~Q-ny6-CfnE^4**j#Z) zHZA|9aMSFaPfYd^v;1cVA~<5^!r-?V@KiI^Zc(hNJy_Xt>Q%u7mTuIp8NztqONdyr z{QXzzS!1-X=RrTiy0GwY%Y4QN*bKI2H}hFsCB&`KeG~=W3XgwO;T|>u{Vp8s3#A|r zA%X*WC0>Bvvj?EuMjxhOr^Ga2N(-Ld3BzAXGFrJR$|Z%-wb z0SK*L3D)xtN&j&#MUq;R4)O=a1Yg#f`||pTc%5cpEDD$ew1jj>krLlBC9ED%M1eOR YI_$%~;K)P0XL-fkkxmpO2knr#0F2PuNdN!< From 1f37c3ee868cac9fea2bd38db148c51c214df2ff Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Fri, 19 Jan 2024 06:41:31 +0000 Subject: [PATCH 16/21] Bump roxygen version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 84990f7..3b5f901 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -22,7 +22,7 @@ Imports: glue, RSQLite, utils -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.0 Suggests: arrow, covr, From faa5f85db4cd3d24e5c0aa72bdcb04e8c25e01d9 Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Fri, 19 Jan 2024 06:52:08 +0000 Subject: [PATCH 17/21] Exclude RPM PIN from unit test --- tests/testthat/test-tax_bill.R | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/testthat/test-tax_bill.R b/tests/testthat/test-tax_bill.R index 47fb2d7..16250c1 100644 --- a/tests/testthat/test-tax_bill.R +++ b/tests/testthat/test-tax_bill.R @@ -167,6 +167,7 @@ sum_dt_no_rpm <- sum_dt %>% filter(!pin %in% c( "14174100180000", "01363010130000", + "14333001380000", "10252080490000" # TODO: This last PIN has an exemption on its 2022 bill but not in the # 2022 clerk data. Seems like a new parcel, need to investigate further From ddfe24b8b12f2991613ff7561d6f1c9463fa519d Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Fri, 19 Jan 2024 07:24:38 +0000 Subject: [PATCH 18/21] Add release checklist note about sqldiff --- .github/ISSUE_TEMPLATE/release-database.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/release-database.md b/.github/ISSUE_TEMPLATE/release-database.md index 6fbeaee..055c32c 100644 --- a/.github/ISSUE_TEMPLATE/release-database.md +++ b/.github/ISSUE_TEMPLATE/release-database.md @@ -20,6 +20,7 @@ labels: release - [ ] Using the command line, grab the final compressed database file from the temporary directory (found at `db_path` after running `data-raw/create_db.R`) and move it to the project directory. Rename the file `ptaxsim-...db.bz2` - [ ] Decompress the database file for local testing using `pbzip2`. The typical command will be something like `pbzip2 -d -k ptaxsim-2021.0.2.db.bz2` - [ ] Rename the decompressed local database file to `ptaxsim.db` for local testing. This is the file name that the unit tests and vignettes expect +- [ ] Use [sqldiff](https://www.sqlite.org/sqldiff.html) or a similar tool to compare the new database file to the previous version. Ensure that the changes are expected - [ ] Restart R. Then run the unit tests (`devtools::test()` in the console) and vignettes (`pkgdown::build_site()` in the console) locally - [ ] Knit the `README.Rmd` file to update the database link at the top of the README. The link is pulled from the `ptaxsim.db` file's `metadata` table - [ ] If necessary, update the database diagrams in the README with any new fields or tables From 20279cd145bcf05dd7023cee087cfe15daf3599d Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Fri, 19 Jan 2024 07:48:45 +0000 Subject: [PATCH 19/21] Fix broken links to GH issues --- README.Rmd | 10 +++--- README.md | 45 ++++++++++++++------------ man/figures/README-multi_year_4-1.png | Bin 22799 -> 23212 bytes 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/README.Rmd b/README.Rmd index 71eb286..b9509ad 100644 --- a/README.Rmd +++ b/README.Rmd @@ -173,7 +173,7 @@ There are some minor differences between PTAXSIM and the real bill. The taxing d We can also look at a single property over multiple years, in this case broken out by taxing district. To do so, pass a vector of multiple years to the `year_vec` argument of `tax_bill()`: ```{r multi_year_1, message=FALSE, warning=FALSE} -multiple_years <- tax_bill(2010:2022, "14081020210000") +multiple_years <- tax_bill(2010:2021, "14081020210000") multiple_years ``` @@ -208,7 +208,7 @@ multiple_years_plot <- ggplot(data = multiple_years_summ) + annotate( "text", x = 2015.8, - y = 11500, + y = 12500, label = "RPM TIF enacted", hjust = 1 ) + @@ -555,9 +555,9 @@ erDiagram ## Notes and caveats -- Currently, the per-district tax calculations for properties in the Red-Purple Modernization (RPM) TIF are slightly flawed. However, the total tax bill per PIN is still accurate. See issue [#11](#11) for more information. -- Special Service Area (SSA) rates must be calculated manually when creating counterfactual bills. See issue [#31](#31) for more information. -- In rare instances, a TIF can have multiple `agency_num` identifiers (usually there's only one per TIF). The `tif_crosswalk` table determines what the "main" `agency_num` is for each TIF and pulls the name and TIF information using that identifier. See issue [#39](#39) for more information. +- Currently, the per-district tax calculations for properties in the Red-Purple Modernization (RPM) TIF are slightly flawed. However, the total tax bill per PIN is still accurate. See issue [#4](https://github.com/ccao-data/ptaxsim/issues/4) for more information. +- Special Service Area (SSA) rates must be calculated manually when creating counterfactual bills. See issue [#3](https://github.com/ccao-data/ptaxsim/issues/3) for more information. +- In rare instances, a TIF can have multiple `agency_num` identifiers (usually there's only one per TIF). The `tif_crosswalk` table determines what the "main" `agency_num` is for each TIF and pulls the name and TIF information using that identifier. See issue [GitLab #39](https://gitlab.com/ccao-data-science---modeling/packages/ptaxsim/-/issues/39) for more information. - PTAXSIM is relatively memory-efficient and can calculate every district line-item for every tax bill for the last 15 years (roughly 350 million rows). However, the memory required for this calculation is substantial (around 100 GB). - PTAXSIM's accuracy is measured automatically with an [integration test](tests/testthat/test-accuracy.R). The test takes a random sample of 1 million PINs, calculates the total bill for each PIN, and compares it to the real total bill. - This repository contains an edited version of PTAXSIM's commit history. Historical Git LFS and other data files (.csv, .xlsx, etc.) were removed in the transition to GitHub. The most current version of these files is available starting in commit [1f06639](https://github.com/ccao-data/ptaxsim/commit/1f06639d98a720999222579b7ff61bcce061f1ec). If you need the historical LFS files for any reason, please visit the [GitLab archive](https://gitlab.com/ccao-data-science---modeling/packages/ptaxsim) of this repository. diff --git a/README.md b/README.md index 2f45315..22fd412 100644 --- a/README.md +++ b/README.md @@ -434,7 +434,7 @@ broken out by taxing district. To do so, pass a vector of multiple years to the `year_vec` argument of `tax_bill()`: ``` r -multiple_years <- tax_bill(2010:2022, "14081020210000") +multiple_years <- tax_bill(2010:2021, "14081020210000") multiple_years #> year pin class tax_code av eav agency_num #> 1: 2010 14081020210000 206 73001 69062 227905 010010000 @@ -443,11 +443,11 @@ multiple_years #> 4: 2010 14081020210000 206 73001 69062 227905 030210001 #> 5: 2010 14081020210000 206 73001 69062 227905 030210002 #> --- -#> 133: 2022 14081020210000 206 73105 70000 204659 043030000 -#> 134: 2022 14081020210000 206 73105 70000 204659 044060000 -#> 135: 2022 14081020210000 206 73105 70000 204659 050200000 -#> 136: 2022 14081020210000 206 73105 70000 204659 050200001 -#> 137: 2022 14081020210000 206 73105 70000 204659 080180000 +#> 122: 2021 14081020210000 206 73105 70000 210189 043030000 +#> 123: 2021 14081020210000 206 73105 70000 210189 044060000 +#> 124: 2021 14081020210000 206 73105 70000 210189 050200000 +#> 125: 2021 14081020210000 206 73105 70000 210189 050200001 +#> 126: 2021 14081020210000 206 73105 70000 210189 080180000 #> agency_name agency_major_type agency_minor_type #> 1: COUNTY OF COOK COOK COUNTY COOK #> 2: FOREST PRESERVE DISTRICT ... COOK COUNTY COOK @@ -455,11 +455,11 @@ multiple_years #> 4: CITY OF CHICAGO LIBRARY F... MUNICIPALITY/TOWNSHIP LIBRARY #> 5: CITY OF CHICAGO SCHOOL BL... MUNICIPALITY/TOWNSHIP MISC #> --- -#> 133: CHICAGO COMMUNITY COLLEGE... SCHOOL COMM COLL -#> 134: BOARD OF EDUCATION SCHOOL UNIFIED -#> 135: CHICAGO PARK DISTRICT MISCELLANEOUS PARK -#> 136: CHICAGO PARK DISTRICT AQU... MISCELLANEOUS BOND -#> 137: METRO WATER RECLAMATION D... MISCELLANEOUS WATER +#> 122: CHICAGO COMMUNITY COLLEGE... SCHOOL COMM COLL +#> 123: BOARD OF EDUCATION SCHOOL UNIFIED +#> 124: CHICAGO PARK DISTRICT MISCELLANEOUS PARK +#> 125: CHICAGO PARK DISTRICT AQU... MISCELLANEOUS BOND +#> 126: METRO WATER RECLAMATION D... MISCELLANEOUS WATER #> agency_tax_rate final_tax #> 1: 0.00423 964.04 #> 2: 0.00051 116.23 @@ -467,11 +467,11 @@ multiple_years #> 4: 0.00102 232.46 #> 5: 0.00116 264.37 #> --- -#> 133: 0.00155 238.81 -#> 134: 0.03757 5313.22 -#> 135: 0.00323 497.64 -#> 136: 0.00000 0.00 -#> 137: 0.00374 576.22 +#> 122: 0.00145 225.36 +#> 123: 0.03517 4984.70 +#> 124: 0.00311 483.37 +#> 125: 0.00000 0.00 +#> 126: 0.00382 593.71 ``` The `tax_bill()` function will automatically combine the years and PIN @@ -509,7 +509,7 @@ multiple_years_plot <- ggplot(data = multiple_years_summ) + annotate( "text", x = 2015.8, - y = 11500, + y = 12500, label = "RPM TIF enacted", hjust = 1 ) + @@ -863,15 +863,18 @@ erDiagram - Currently, the per-district tax calculations for properties in the Red-Purple Modernization (RPM) TIF are slightly flawed. However, the - total tax bill per PIN is still accurate. See issue [\#11](#11) for - more information. + total tax bill per PIN is still accurate. See issue + [\#4](https://github.com/ccao-data/ptaxsim/issues/4) for more + information. - Special Service Area (SSA) rates must be calculated manually when - creating counterfactual bills. See issue [\#31](#31) for more + creating counterfactual bills. See issue + [\#3](https://github.com/ccao-data/ptaxsim/issues/3) for more information. - In rare instances, a TIF can have multiple `agency_num` identifiers (usually there’s only one per TIF). The `tif_crosswalk` table determines what the “main” `agency_num` is for each TIF and pulls the - name and TIF information using that identifier. See issue [\#39](#39) + name and TIF information using that identifier. See issue [GitLab + \#39](https://gitlab.com/ccao-data-science---modeling/packages/ptaxsim/-/issues/39) for more information. - PTAXSIM is relatively memory-efficient and can calculate every district line-item for every tax bill for the last 15 years (roughly diff --git a/man/figures/README-multi_year_4-1.png b/man/figures/README-multi_year_4-1.png index 68aa02d48fb34f646b64f09257dcc84bd713ce34..661159afd1f5aa9136045d65828474a50106b17a 100644 GIT binary patch literal 23212 zcma%j1yq%5*X>47Ksp4G4ngS-DM=9!6qGIj0cpuir$H#7gh)w?v~+{C64FQ`-Q9K9 z_I&?$zyIEU+;R69XBHz7$i z;)N_x+e1bk}l>hW)mJ>TSpz{X1CtT%fQv#)sodChyNo6 zU;APr5QKCXVhDsUf_@4Ofxy5*BYSAy=W-wLSmo(CHW;Pecg^E9uoB+3)l7S`v)@YFYgj{G@V)MIt3Sm2ybG zkx#8~UeOrJ)32$i(H>>^`TO(3TepIZk31UY=O42^QBn%2suJy^wAAL;^oW}yU@gE# zBcQ`zjavTG96}rvSmKL0nnJm3#6q}Fykm6X&MbUe68I*c}F3v~FwD4THk z7aE3`FX5Z!KW%Lap#?=GZO+`6FVWn^x)r>Aa1f)Iu19`JS?Y_7IqDf5;#A<9$<(7G zuFqFHJP%nS@IFAdvLR2#*YJbK$^E(Lwv`*JdSE$;@o^m~f*SQNPcPs2MTc8HjO$By zE9%Ea?MdF(ufZ$Q)-=7;7;p)6gjZi)BF8Tz?4=IG(BDNM-nbCb6;GknPtcD`g~Qbw z4TZ1MJzh+~B)k-y;_2xbpO8?&*%VDTA~g(uD@{ihLhG^0#&Ieiw%Zv5J*Ky^5&=hv5oeH`4s&kBOL;DGs2P#(_KRx7-`Z)?8U$F6RskgTGEf z9q_Y8w%u5H&+u@YGktY{6K2&*PIm+$v#jW_2wc`(-|%$=JW9eFX`%=za&ZI}b_(@f z9MrQnE=0D4(@RK5=#hWFnI`JX2^WHeCijRqsHvgB`{LQXO7!BVb&{9}I@~udhyc{3 zP`+})v>>=dgRs8VOZ^%B?@hjyS2r}=SVet0oH?xT7NcK(Nd^n_rp*MsuVnaPDbRDuz=jqBTh*5u7j&o@{G2h?t`+CtfXT(ofzredp z#CwZ9jh&ruSESkf^)L$<{;s`j$~_vlrt$HF73mH?JxrrZ_#e=t#SX?CBj3HIalggN zYPryrusaq+!eVJ2B%4xSUq58vk(-zIj*ys;@b07jC^pTJ9ByIZk11bp$T=5PlvPwR za4AGx*y&B%-`}k9ILM%l{q*VUMZvS5(LCqUi(hhcZ7eJn`xz!CCR*Q7n|z^(E@A(q zbn!wT%a=R(GQnz4P|(q4Bf-+>z`%g0>w5ehXUi}eaT=e~7t(Dcs$zvMYdX?z^f)i} zN9}~HhkyP0Rp52vB8?^Y$YXz1yVkS9<%yh}oRIC|4i1^*|H zgY|2qq!#2aUcA62Ah0V+?C*aZrMP#rkffB}>vM53dH?=>7S+Vv?QMp@4p`jrN@v($ z=RZU0BhSv<`nVlZE7J;cCUyU{p&de;)OZ&T07WLv%+jSL5fL z!=T_jpGJ!D6vgx(?d{3vaq^G)V+_412np$8em-Fx7&7$96+N)?IT>wvOF8FIA)or_ z7AfjxVGkd+P}&hnfBW`LKJ@zZ;-Ui9b6Z&C=rnVrv4dJGmlSIutkmq)2s^h(j} zzbhOUxav-ciHUigm;2%V6U9BgKK{Cp=waL7f7zkpbhyw&Gv7emX)!!3O!e{O$Li|p zusy7-*b*W*I5^g9+8P?B8v-!l;6wOfN!(ARp*o$bYp_P`?d?5y@F2&_deLcUGTx+x z*ySoB+rq{MilZ6V`tq{kqsVJ3Xl&nNd|e$-A6}2G`FS&Qb8~X?{jMl&L&NTQo=!Lj z#8wZ-9bw@`{BLY*Y$vNl-DaJiq9P+_=jP_7ran`f-ox73-^a(sCJK@bBn(c08Ufb` zIZOA+lWR9_xG(-nmJ1=PsH`NGPE*Tj_?E7gwLTUdP4-fHdUlqHIB4-UK0f~K+qX{+ zHa0%bZ*M!ilqR}<{flT}X=$`U<7cS=2w!ygW>wXR|79F}>N}B9QOXxE z#=MW_Vm3E7KYylk$IGwY{=t@CEsaGK(yXGQVry%=X7i=6@WoWU9~v6kZe&mDJ$2HX z5emCW-=vf20)<6Ii}nk9EcoBPeLK>bj5#4+QC_aKJ&NUN#)U@U`B}7$Q%vkMD>HF> zXGhfM{8U|4T<-i%n@UnxSoa52i3;=XL`ch!E#6V^y|PW^)8CXK5Z_(NuUl5>FV)=T z>KGXwzD`cgLKecJ60aaMx6qxWiUpgC`oOfbEO~d=X?#B7!-o&HESR)(Lug2xfK^{U z$V~6vy@Rb^6%>{v{KDAf??+nNKQoghwWQ~Ge@$0i-Er>6wL&d+vXG6j3O)!VNOJo$ z7vrvz`n8@%qjq%^H9juRsgoavgY}MA*=H}-9{{8#fwQI1LhTlws^f>Dr7gS(#mD!GG zD95Tjd{_X_%;$V3N#+$Uec&6}lGzr>AFTO!gJwOVa*QE{MBWz0`N@;gAKcaD`IR z_2|P~vZB7efJ0V^05okD5WoSOjJHg}#OD_l%zp$#tRwaj97qKH=UYEoTU!@-9N>#5 zfGi7e;0KQYIF~RS!3z$BMV3NcpZGMK+V}1)(yJvpxiuk9m<5g&4d_^YYFVf2RU23E zZuDns!Wj{SfN?(OX!rbCZ*e9<)Z+lm`X7)#9R{h~(aDJt75CRGi1WYqRj5TpL9xX6 zV!DzLF@*z1xm#X$fIoB-fe8C7Lx8xmCO<^5L@Dl_&}efL@rwppiR<@R-2Ie&x?Z;- z5#Df_zG!PK$A+YBSiCg8|Da2?tgAj%eT{vMt1n!bnJXns#SoHzky&cb>Hg>T$tNRO z>9$U1zd~h)UWZ~%(ZgA(3pG+!WLnTS@n8koJ}NnRUFPkb(Tpy=jF5+~V!Z5>9V%nl zZVV#td4oB18HMQdPRjbS64O#dx3;FsiQycoQ_3zGl@;3Gov{&DBF)rB>(Z{C-FM;=bxA7UG^oEF7<&wVYyOoQ{NS(@pZ&HR5>&mVm77` ze)8%5i}ILpC%8@9<1l)fA;X{_>{q)}9 z;o;6WA*+Sb;^K#-&Rc()_sR0JvYuO8_b1s-_*XVBDypcgpYqLIzcisd@^PV(umDGp zd`+hf$=&>hh_MSw5|myj^exTJor&TnZ-pj4n+G-jd5J^*!*tF2xb-b%<_Upcv>Q&I zcG0UmQ$T2e;WneCJ+4DJ+9q8jGo+P^9RAch^~I8RX5Y$H$;;fJ3~G8QEc{JP!~AnT zO(>*SN@06CFAu;zL_|d0k{71{vB+-RSe}~NobcFic6kY<3_7;Z%Z(^F2YEd(93Z8f zyu6FcO))>R>hxbG1j?V|Rx`>*1}wLKa;4S!O@Hfn=_2OzW48SRIy!op&8YnONS`<0 zpv6Uttj8me`1V$YNTiL8ja3rvl-N&y2lzrPeJl8m>$)D~68M@kc}`YVEdTTO%FHj9MpZ)7$?@W&*-^i7Dl~Lv#x=Gzqh^ zf}-Lbx9!=ESU#v27l1;`K7TgaoNBNd%n@;z#X2iE+F4MI6SQf3g*S3}z;X}jk~83? z08E0~oi0(`GF!<1Lxu(DaHzxclMO2?tEDPHf87!%?DVq-lRkz}B`|3{H}{4NA?KEt zmmeRyODkAfT0VciL~iK$;!hKxzp$pJCP?GDE6qIAm5aIeMLTH3_l>TQc+A+4A1^mJ zL8bcz$R$N|ZluKO>dQZKF@{jcy;loczc)5kxvYJyGjed)2GoyD4?tx%GWA}VL6r-K zkkHWRsHmVIVAw=4w{PmrV&{i50Fz(iQ@d|9lXIc2ZF}yvdd6c-&Fq0?0?AYR)5ER6 z@Kzd+oO@w3Nj~RCzG&#R01crxLAtpSNtfD;?nA$_FAjTJUf1e^E`60Ax-JZAYE=S*7bnUfon`n8b+Lk94IND6cDP zYY!&9&W{!(&vyG%uE{*=Kirx*SR1{E^}EDM)7sh^nxRGQt*xzHydYU(N=jWlJx?gd zFQw@}v{O-|KKgokU$e7)&Y}WV`01u7{AfJ5BhF;2$arZ&doB23b35AG7p%($$vPbG zE|IXP?5>R-6m?7BU}KBePx+pI+no~Dzxq;|olIA&HxQddC0@7(nk=g!&dS$!leE|Y z+d)^PU+MH{@s|ZZY`dZY1RtCy@Z;-!Cl}m=M+`*RR~hp12DK^stQlqwWWB#!v^qc9 zH-<_LxZiWVV!?@JettgBpvE0G6$J&w%a<>qV5Z%hrnp8!bH39pDa3!ub7c=84h6T- zU2~-yV#tD+m?6=PYR8@V&dell9Z_+pjI}*uW1jOJv4FlLypCbLtT4yMYrQ;veU^e} zr*2+mA+j1^PUX@O!1>ChSeRlx<=jdk|Zm*{7qX*)VP z0!*W4;Sn`@UZh1#dNl3^I z*m>?}j3F%OTG?bGgzRmcW#S-NSm%|&TuK4U$o#IDHQ4UtA@l*hTf!E%EU>Jp<_3+6?T^;l)aLF!9y>kPah7go2 zfyxlJ(BeLM@&sUyK)C}Z=Ii))6y#xIX1*gTD!J3a$EK0P{j5QdS^48;&pq0brKF3+ z)G#tG13d$Si8`N)4=k#^7i^voE70!8OL)1Pn3#Bao-QQ$*d9q-;(K@lZ@Z;@WMm|D zQfJ|{NX9Ed5|vOCt1&(OG>YR>N^Pw{Y7f%g{ab1CKky{j`1yjIl9G~)OhA4r z3Ko-$ig<{zAm6{ib*|f){q5}gLu+Psw#oTg>GZE;8Av47&dw#W4D^BVqOP{E-iqn( zKWqwK*4eafyk@o9`Zi1t>+Bul_^4~@%4>1&Io`_@<3;b7Yq^0)fwndW5+ww+Q{^ZI zhL})+iNU6==d8a*)$OaMfrMSWiDxeyhePZ_ybq^eO9fmJKizDsY#kC26}2LWo?*cd zi-B*{YpJ-Fe2UbgCy-PYdmBdfC*cysQp2&-cQFd$Fy`6^Z-Rnub8z6{;}5RA4GRut z<>Fc>U`@6ENOfR;D`C_6;{BSddMZ6fu57xQTaiYi+1U1}uaLx$S(z+D4`Z0v_ffC4 zH7T4#ayXU3u&S$|&F=Zn@z{f$QZuqE1EY#Az0N7O3CN`Dciz}`V5SYc(8c|j$^U_P zBD_*CdBQCEfoXNFY!zpdm=>1)ZnaF(Mcy*s{yQynE27?Md&-)N1M}So4bwfQdAHZq zj|BC_>~T1diLBuf+<8{MU4OX8ZwD)+H+|O+G`lAtIlAQ^B+ozBAST@N_I?gBB~Hc7 z<*L#KzKWBH2<7;mZS#KFHNHfxXmkG{7cY%4xA;Z*`d|JFC2CZ+>=>=t#&e06FQV8P z1I0MIf9Z43j%;00asB>t=R_y(S&yC)nJbD$e8Rwug*0FbpEea1tY^M5sLj(qsywaQ zf+IRo0;QE1Zj{=kWrr#WbC8F0`IulzY-WvV#F>7+;TA?U-thU&=8-PsB71GRsAzKD z1u~C!0zXxs+?eK$uWuRNFh#fO>F>STo{%=SpbrE*9#mfDGWtF*qWLDeQuSl#Tss2h z2sca7L}%RIuq>$v{T5*D)st%?W^h?+`bPGu@_b~t9VuHS!9OQOduhVV$XqOc^QlpS zTg}!Wp7U80-={4N-I%-d^Uip*5~ol!1H++_Wnp27P?%j_*3s3aBqAyVv@qTHx~i(G zth6*()+c_`rrs9~5>9-y^)oD_u7ARoSi@0$WtY5YYI0s3$2`wpc55imo;hy^1khaOU2?B$BHCdye zcuRU7Zsuqg0Tq)Wx&oKR!@~pJ-R}6$7%rdPo_o+ zy@OEnRmqa{RQpgX{?k=yOeo(seeU?2iw(_b#YUmm78LwyZ8b+BK=(bJ0wXC~TTbya z=rvJf98mAYVb#d3l%yn7^3~JR1I!6o)oIAYK5vO6w(-Nqh4w=m5A{#&%Rg=ZG>@IL zY401h^GXx_SyrYxEHT8T=q4%kzAruxywA@Ieqd4Zeirhwx%P;PifU?V0(&E^(48m_ zUEF)g7=b`Mu)g;$pU@i<|Il&KEMt^6#PrAf4y7cNR^yEDYp~%0GUsRpGDB}L|phNf2t|m2=u|<6+Ito28<%`e+GBqd1 z8X#Y57_B7KyY0E3coMyxow=2jpK3W`evXfgg~CFoNVt=S{O-;!EiJ9lrfTu@3l&>g zFpqjN?NCT9`ops_j(Dv!YNgWp*35&+Fr&VReDTPx#zyp*kZY`Ln4b6V2Ze-$0N%ZN z73jS|X#JO$mvLKO)z#Ix+#SoWJ73<|uycZy{oVScW2OyB#x4G*;Z9E;ecBT#swUZv zzEp+7q^)QIqJrGE%(!jU4+22Qmjgw(EvQ%N6jTd9re02DwQ$=`3TiltdF!#jq6bOG zvZS(x+1b?86e^>(cC1dWg!`_Ao*tF>8MNgN6=PF+eJl}#n081lzsxB?CtGctnKUX?+*-$J_ zgf~*`wE2hLHz!P<)$2rIg~B=#rf6gXk?;-ZK%q&`zR>ZBOqGOXprzvYX6;odH~DE= zs$Wv?VIjS6(?!)!Mr>H7ugiO>JVsBY^>|9zH zr<}F39TNuvMg(p+tZ;5QvgCDXXi@48cOYM-)QArTduH$@5}*;_O4Y|TS=9F(67I}9 z_cKnF3@f{eE`@Jg$D!zUD5f-hI>C1k;^#}wjZuAH85enDfyYiB4*q;KP1KT^tRpGcuHZ}!eAXwt zQatsbH;b&AGf!tHVVok2OssIC{!T!}cenV>q-&#FVqyF5Vz*PDHYec}PhH04K$^W6 z_{0S@cO|FYfIDVgER5v5Kv8reBQ?S7N7$85+eTLt6H9fBl*LECJW-7evTBLz(pgBg z*_ntvuhsR_kqNf@aPolN<{d?J{LjHf*H-3U{hyHp1YKS@Aifo4s`J=g6Mj&0`}z&7 zR+o4S{I5{7TFBbMw_332$6uzaQ*iZL z3_UaMkfDT)l78z)bF&;ngu>rO9=N=b;df3ih(DUmYA%OsYD%yuQ`8zcIXt#gK{XDf&1Q@|>z z-B=IY0w8GtD-N<8P>N>Vi4Rou3XB>u9>hr;P6dE`K`rVsyRe`dFC38wSGc{Nt!5mS@-lnkJn@==QpzUa(ofYU+|KJUatiaxpfYUj-2 zqVTgHk-@=Nr4;~tM|0?+2t_}1%sV0?drN%_o70Vwfciji!KMec+obg!v^&o|vK?Gq zlLV|Zpgjkw{s8SiXKaq~ z%egb;gDB9{GD#t~5nyL)dw#mpZDMQ;Pu<_&pOuYmR4nJ)H=rP8J%l(oI)V0w{_MG3 z34AKO5T}8@3yf!694;-oL@qU>Q~_N13HPcvL+khynTXTV(hiS~u91-efipKdi|W*N zf_tX_%L}j|C?vE2{TDFxBezNAY{tr8{QmaLb$yJd{5!O#vT|}f24&9(H&2^oTT)YL zmTXg<3{7RLq~09i1C?o4dz1k*EE7{2?A7PbpF^L|$b>v4K|I?(!sg@qvTREEgP z%Y#hf2KCEEW1zo(cdM1wXQxw$&%DcYi{c|XTDO%(H&S$x!e<{2%k34&%s`x56samTZeWZ9{DQ}Mu2I6BwlL$JEhKAUj9|p$wf;^ z;A<4#!^FT?9Vuaxl$`AD4nu89J?j=GGeheZhvUq&(o>B7QPm2UPd-7-sE01B-XQ*ueUFxsI_vujBorlOof-`tcB0IT`X`;iNP1QiNj^bwPap=Z8(Bn%?$f$S(>N=vS zx<;yglsMa5Y|^F0v6o-y>Jq-R@!tB~DUQ$-A?(+wi+d$U4muyVcm$ZN6JMP@+O=uv z+}@Y<5d5%yL)zPp$+oMBB4D+iX_xE%g#G%x9(0*s{$*}tr87$jTWHUn2ftB$le-)o*w zxHT)(hf#@a19xAkzCKxZ0W=(_NqpMZu0P$Yv3Om(9hya7xAdUw^{j1}e!?0KBCyrI zUPw^TcA`3#&|!D62cYY67i{#OKYyAe^DbT|30Ri;8GUB~4S~x;wFz2Sy&w9n%^Kb( z1t#}{aaW3b9A%@uP|O>>)Ci1v`}&`z-$3$BBqSywk(mSrxJ5T1H=|1NL6;#5{kiOX zgY#|RpXK)($Vo~0g@iy!sOsFEnlfrp^zV{t(T&K>5JmXXFlu&pbam~6pw-i;^1_IL zIgiTjHL&uRQhO|T`S?!uRu<;x$$%vRP1MTV>vXFXC17$`U@E7%(uvWsSk@1IH?8 zH&G43{Y+~Zi8L9zRso1F1QLgzGcwG8R)vNI0y2$!$tYUm(W4$9rs__&e}ep1bQXE1 zu`PC$i5SI^0D{+Mdy|B8X0F=TI>2?^mlv9{;TK3fDn$HGAc+Bv+_9gk2i4ox7vb*i=;#Rl23Sd;P)FnTfQUFgI=UV8V`V6xfKm{J zMj^zbBRelKavTDk1hQa(`c*9~>OC`(?^be;nuhQevM&E(Wo2FN%M247$EF9y&_Q0l z<)2iX_tsweO-RU3zHYG(adD#!?8oc5x@Dk+_V)E1C9O9t(p6n!(}2X8SzKJ~b8+6) z)itst^BVtIIX5@vm9bbUx`Z8uU@>B&)29fR87K*rk8+)%^8t^9AW49~e^g33Kik!vm39Vz0xBadeF^n2_@#HMJLT?ojO3BB6d-kCt+9a&oe;WL8${h}Kk8xB)K*H??L& z=H>b$@;2P$zZhJ7K1mAf!%CL|b*hhe6n3N_=?qsoE%5>y50w#!Qtjl2pcv=qRX6|( z2YUx(D@wT0r%#g=(^)w4eg3V#*xh1EOq-K6yL^-dx__2p>@`I=egr>_d)i_(PfFr@qu6$sNicF`a_mPqOZri4i_?dCg z+3I~o0|F}=rE}>A_L}rj2AfY2UYp18GyqVGT!axQ2PSOUe0BuWQD6kwDR6<#8z{2O z@ZwlgOY7r0&sM#oMXMG4I9k0ogdrgO(%9`^G6Vn(-WIz1615@E@^HXagcTRzYX=-J zU-Q5~RH3o2lnt-J7v(WbKPOB?10V5bUS8gfxAUM4+`M^HG5s4*$*^+iw?gE_F41Cr zCbHW{UV55Qr6p_ZA9Q{40pc(qqH)&J%Ie-bD(%OQ`@u63q2L4?b#ZYK2-m~o<8K-a zw8M)}9geNH>P1%YaY@Z8(LaU|ylzL62`!#l=!^sH_~(xw006M)0hg!(uX=j4Q%E@> zzvXEz))#OJvYi;IM^j2-CLiMqs_Limmn4AsU}FnWag|muGMe((s1bVcM|K_uJ;Oe6 zOZYJX!uPWLr3t$D%)vpP$SqGL+u|X#`b5}gK#y?g6k9;Ey?fJvjg@u6bElJtQNBQp zlKYE#!17V_mUG7S~W3NqxmkN zATwFWwX4mc6np@g6XN2ORJqvM(?$yg1O$Nap%k+1&u}m>NCejaq&Gz+C1AikshPpRdl$O%=u{A@etB~ z{sGUieCEsD@7qmbBjx1e^sBW0_~AbNk{smjZ*T{Y)?EtTynfvZZ9Ex=PUQRd5GXMm zx}{)jym#;3m85n<3T$MdR<%)sKP1NjHC+2Eu{Jxhq)Y4f^j`2FeO0V1Ek{6BcX0T2 zo&()6I4wFll#lb&vc$ma^z`X8oB@>z0?_iS+ECsuka2)90GlCrn$pskWg@M#58gzkx&=>;CD^ zmG?BO8h;Eo{!}3ZRsREO*?|>|Yl-B!Pq9OTl*Bl0#5t^jN&35>W$F4KZxk;JM&U!D zhmfFV|IWcU6fg<*1JVY{{nxjUGW4xX(96aqcXdIHgyxM4uDxt7J-OZcb?>Iu+#MWU zw#2QYGI7sx8Zl1tpM;FLJHYrP5WWZa^RJRS`YO+3>W#e2r)#q5f@?jv0_8k}*L?4V zVu<;V=_$BRT^p?Y6|sfz>{&Wnfkp>Plh<67=EpDcZ^C!$vGHAlO@^rvT-PZ~Gf@KQ z#p!}1Fd|^}$*(LoE1+zWmg z# zX-4GcILb_4JP_l2ZT4~6x9-JE3+z6Z^|7O+%%tPv`mtA= zW7HeUt31hehCVt$)Ya_SvnLuFKpGe2GY4$*ZyI`&866 z^ix||SBzv9-hE2H#R^!8lk;7&0KYrhL ztXc257~f|vHj?u^f6P+qScNw+NMN*`W$A}$EqQ(Q6GvEFw#P1)&v8*lYZ-Z3k)68n ziBElDoRFOwDYyfq$Aduf<&6y`Oi|0a6C6%`d=;MP!znYp=U&$qa|z5d{*x*u0mJOS1r*jHxXm}y3;=iB7ePStU(y-@{6DO-XMkF=xkC?&m50aY!I!s@9$cp&gB>q)l8Gjnspa(ln_ z-s|Q}Q(SuGD47{dV20$>Yh?ohP}gcw!9@c zG+GdK$L6l3B`ftNghmXfe(>A30?%&K(k8*-JL5&vb2a$%=mJ7l16=LxwW^VYdYs*D zZFGUF04yK~b4bk?a|GjuafN+fYa)+yI|eR3dyd`g{wdTZ?AgfyURS0lMI}W=aJfOa zF_DEl(BlSEC4l;~*$=AMIl>;vU#iW?S&h;(K*fv8#suU`aj)ZD=m{VOhWh$GBph1@ z?YBk_q%AZeZi=>M&Q5t>^dzx&B8}4t1d}GHcj)Iiz?4=F@Z12b4bV0YsgQ;=L##u= z+S%Jn&jhwih@1Q22_iT}(01%&czAepbc;)~hH+X*t=(iTWHV4dVufG)fnWj*-^!+$ z2h>K9dVH>N6}sVd$)}}ngc82&F0373rA({4GQ^DU`LF&Vo8U8U2eTe{S3wU#-OjR# zs)`D#X90Blg!KvdBVAnfKk}G3(GpTnh=AV&k5aHeH-7-|u@`LV(bCS=*4MR^R8;XX zF=ZA#4D&c782j&O3_YT^W->Jn&@ zSmdrPG>G7T=HcmSZC%JMn>hXx!j+PmI?5gw5iz~K-ep`kXu8~NR*ZtkZ*Mq5QGa#y zPv*#o&hO`%Y&ma!Pk8K375ZY<Z1gf; zj8l-&2s(R1Xga`B0mjsk+aT+UyYCv6-a<2Rkrdx=W|>h87!8UxZ1m@-CTRYmu(llDe;En0PnhAKG4 zG_LCttTh;U9O5u?AcJJ3Y3FIl$iUg4jD@mUfUHKD{+rS&(GTOIOZQ#X(68z+KLy#- zOF=~f^1<8>!Y|4cAZo%Mll<`^AWmSo*h97Pf)OGy|hxC#Xl%W=+lBc<{ z5(Oi-j=R1|*NGpmD7QY!8|5qQzOdj`pCF$go7A``dCBv-907`tX>V_bBVgm;q;6R9 z-v~|t<3!!bx~QR{AxZZf8&mvcF{zfKfIW+{9lfFE?2pBNPQGU^$SHW#p?hK>SvQJr zhFJYcD$uxj$wYYScJLi&YJuMQ&Gja!92fa1U6QQraKC_Zt<5<=xLZ1UlKfrLhM_ke z;pQbXQ®mvSay*slgDzZ(}b4vEUwNyInNu-HAoq+?-xh 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

n{s=AXRd=Vtu} zqe()G0-S9G3_2zhh`f%arGYHG45_NKwh!(M#S4%r^zA=-41wmdva-_B(n?|~6J^p& zNhe!rYc7F6D{b-C;031sKQA!BlV>0K+fIY(FC#BcL>(X%;t<3-hYj}S?4ZN{0pTt3 A&Hw-a literal 22799 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 o&No;R_cedR1@p Date: Fri, 19 Jan 2024 08:23:17 +0000 Subject: [PATCH 20/21] Coerce rate calculation to numeric type --- R/tax_bill.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/tax_bill.R b/R/tax_bill.R index 6d6f2b2..5ebca11 100644 --- a/R/tax_bill.R +++ b/R/tax_bill.R @@ -193,7 +193,7 @@ tax_bill <- function(year_vec, # Calculate the exemption effect by subtracting the exempt amount from # the total taxable EAV - dt[, agency_tax_rate := agency_total_ext / agency_total_eav] + dt[, agency_tax_rate := agency_total_ext / as.numeric(agency_total_eav)] dt[, tax_amt_exe := exe_total * agency_tax_rate] dt[, tax_amt_pre_exe := round(eav * agency_tax_rate, 2)] dt[, tax_amt_post_exe := round(tax_amt_pre_exe - tax_amt_exe, 2)] From 26638aee963fd55f27628b25141c480ca84d0129 Mon Sep 17 00:00:00 2001 From: Dan Snow Date: Fri, 19 Jan 2024 15:59:16 +0000 Subject: [PATCH 21/21] Assign CPS RPM holdout to TIF --- .../sample_tax_bills/agency_name_match.csv | 2 +- .../sample_tax_bills_detail.csv | 4 ++-- data/sample_tax_bills_detail.rda | Bin 12617 -> 12610 bytes 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data-raw/sample_tax_bills/agency_name_match.csv b/data-raw/sample_tax_bills/agency_name_match.csv index 6e5425f..35c6c5b 100644 --- a/data-raw/sample_tax_bills/agency_name_match.csv +++ b/data-raw/sample_tax_bills/agency_name_match.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71405da084f2e0f2e43eeeed38df92d170683bfcfbf540102d392148e03104d4 +oid sha256:fc23b4e2eb9c7d1ebca963e2fae1842ad469e51183146e73f5971edfbcc54737 size 8945 diff --git a/data-raw/sample_tax_bills/sample_tax_bills_detail.csv b/data-raw/sample_tax_bills/sample_tax_bills_detail.csv index 0ab28d0..ca01b4a 100644 --- a/data-raw/sample_tax_bills/sample_tax_bills_detail.csv +++ b/data-raw/sample_tax_bills/sample_tax_bills_detail.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:db21c8a42ffa4197f645ecce23c82f8d1be7ee7b50646ed513b2f80ee85e647b -size 57270 +oid sha256:1968dafd92ca407c4247ae4bfcd63d6380749e90b566f1cb92170dcc4e36bec5 +size 57271 diff --git a/data/sample_tax_bills_detail.rda b/data/sample_tax_bills_detail.rda index 8935633cbf78f4823fe607c3be037d1210ce3573..e47e3f79c75d8518c711dce6aea54a1c38c9adb3 100644 GIT binary patch delta 12315 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 B>uLZ1 delta 12322 zcmV+-Fx}6>V##6-LRx4!F+o`-Q(4yiIA@U#D1X5F6Fv00jUA001*!3ZSDp0A2t9000j<2h$%~`oXZ$3!0G?y<&i;P$f~i_YV_h z4u$l2ee7#N&~Z>uIvp#cTf2biK$1idO#qmhGyyT7G6eKSOqyweV47&tOqn#)%?65o zLw{4rrkZIyk>CkDhDHd;#7$3SJxThWBy9|uGM+;O)Y@bK(TY7!O)@l_R3fM70096J zWJ!W2q{P}LOpKWasgp)S5XqxVhooo#8UQo^13&-(27m^D00Te(13(%Y05lB<6w^|l zs(6#s{8TbD{Y+8n0i)C#QKLiD9-uM?kAEmVL9}Xm6UiQk2A`;m#6jvBWb_HAiUUWe zXaTg1217@w`lpIAZA~<7PfU~2XlAC=@SsVlB9qddr=dLvYB4`lZA~(7P?*vmsWiVX`z)oH9aFjewv<;Jtj$~l5B>F;FD@(8feJcO⪼ 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 IYkr(FfW3d@jQ{`u