A.3 Public or Tax-Exempt King County Parcels
Description
A dataset of parcels within King County, Washington. Each record in this datatset is not currently paying taxes - a status which may make them a suitable candidate for the development of affordable housing and early learning facilities.
This data reflects the King County Assessor records as of October 13, 2017
.
Summary
Links
Processing Steps
Summary
- Create
p
: atibble
containing parcel data for the entire county. - Create
acct
: atibble
containing real property account data for the entire county. - Create
p_sf
: asimple feature
object containing the spatial polygon representations of each parcel in the county-wide dataset. - Clean/process the three dataset: prepare the datasets to be joined and filtered.
- Load
tax_status
andtax_reason
for transforming coded features into descriptive text. - Load
pub
for joining the public parcels.
- Load
- Create
pub_or_tax_exempt_sf
: Join and filter the datasets.- Join
p
andacct
withinner_join()
(an implicit filter that returns all records contained in both datasets) - Filter by excluding records whose
TAX_STATUS
isTaxable
. - Create a subset of
pub
which includes only those records not found inp_sf
- Combine the two filtered objects together using
bind_rows()
- Drop any record which has
NA
in theTAX_STATUS
column (these records are mostly empty) - Join and filter the combined object to
p_sf
usinginner_join()
- this returns asimple feature
class spatial object (i.e., it can be shown on a map).
- Join
- Upload to Drive
Step 1
p_fp <- root_file("./1-data/2-external/EXTR_Parcel_20171013.csv")
p_load <-
make_or_read(p_fp,
{
zip_dir <- root_file("./1-data/2-external")
target_name <- "EXTR_Parcel_20171013.csv"
dr_id <- as_id("0B5Pp4V6eCkhraF9jOTl3bURiMkU")
drive_read_zip(
dr_id = dr_id,
.tempdir = FALSE,
dir_path = zip_dir,
read_fun = read_csv,
target_name = target_name
)
},
{
read_csv(p_fp)
})
p <-
p_load %>%
rename_all(to_screaming_snake_case)
rm(p_load)
gc(verbose = FALSE)
Step 2
acct_fp <- root_file("./1-data/2-external/EXTR_RPAcctl_20171013.csv")
acct_load <-
make_or_read(acct_fp,
{
dr_id <- "0B5Pp4V6eCkhreGt2djZCTnFUeFU"
zip_dir <- root_file("./1-data/2-external")
target_name <- "EXTR_RPAcctl_20171013.csv"
drive_read_zip(dr_id = dr_id,
.tempdir = FALSE,
dir_path = zip_dir,
read_fun = read_csv,
target_name = target_name)
},
{read_csv(acct_fp)})
acct <-
acct_load %>%
rename_all(to_screaming_snake_case)
rm(acct_load)
gc(verbose = FALSE)
Step 3
p_sf_fp <- root_file("./1-data/2-external/parcel")
p_sf_load <-
make_or_read(p_sf_fp,
{
dr_id <- "0B5Pp4V6eCkhrRnM4bHFmWTBTQnM"
zip_dir <- root_file("./1-data/2-external")
target_name <- "parcel"
drive_read_zip(dr_id = dr_id,
dir_path = zip_dir,
read_fun = st_read,
target_name = target_name,
.tempdir = FALSE,
layer = "parcel",
stringsAsFactors = FALSE)
},
{st_read(p_sf_fp, layer = "parcel", stringsAsFactors = FALSE)})
p_sf <-
p_sf_load %>%
rename_if(not_sfc, to_screaming_snake_case)
rm(p_sf_load)
gc(verbose = FALSE)
Step 4
tr_fp <- root_file("./1-data/3-interim/kc-tax-reason.rds")
tax_reason <-
make_or_read(tr_fp,
{
dr_id <- as_id("0B5Pp4V6eCkhrQzdjY0hKVUhOR3M")
drive_read(dr_id = dr_id,
.tempfile = FALSE,
path = tr_fp,
read_fun = read_rds)
},
{read_rds(tr_fp)})
ts_fp <- root_file("./1-data/3-interim/kc-tax-status.rds")
tax_status <-
make_or_read(ts_fp,
{
dr_id <- as_id("0B5Pp4V6eCkhrWFlYLWM3RC1pRDA")
drive_read(dr_id = dr_id,
.tempfile = FALSE,
path = ts_fp,
read_fun = read_rds)
},
{read_rds(ts_fp)})
pub_fp <- root_file("./1-data/3-interim/public_parcels_20170727.rds")
pub <-
make_or_read(pub_fp,
{
dr_id <- as_id("0B5Pp4V6eCkhrSUhXdHNtdjBfa28")
drive_read(dr_id = dr_id,
path = pub_fp,
read_fun = read_rds,
.tempfile = FALSE)
},
{read_rds(pub_fp)})
p_ready <-
p %>%
mutate(PIN = str_c(MAJOR, MINOR),
DATE = ymd(20171013)
) %>%
select(PIN,
DATE,
PROP_NAME,
PROP_TYPE,
DISTRICT_NAME,
CURRENT_ZONING,
PRESENT_USE,
SQ_FT_LOT,
ACCESS,
TOPOGRAPHY,
RESTRICTIVE_SZ_SHAPE,
PCNT_UNUSABLE,
CONTAMINATION,
HISTORIC_SITE,
EASEMENTS,
SEISMIC_HAZARD,
LANDSLIDE_HAZARD,
STEEP_SLOPE_HAZARD
)
acct_frmt <-
acct %>%
mutate(PIN = str_c(MAJOR,MINOR),
DATE = ymd(20171013),
TAX_STATUS = tax_status[TAX_STAT],
TAX_REASON = tax_reason[TAX_VAL_REASON]) %>%
select(PIN,
DATE,
ACCT_NBR,
BILL_YR,
TAX_STATUS,
TAX_REASON,
APPR_LAND_VAL,
APPR_IMPR_VAL = APPR_IMPS_VAL,
TAXABLE_LAND_VAL,
TAXABLE_IMPR_VAL = TAXABLE_IMPS_VAL)
acct_ready <-
acct_frmt %>%
miscgis::subset_duplicated("PIN") %>%
group_by(PIN) %>%
drop_na %>%
ungroup %>%
bind_rows(subset_duplicated(acct_frmt,"PIN",notin = TRUE)) %>%
arrange(PIN)
p_sf_ready <-
select(p_sf, PIN)
Step 5
p_join <-
list(acct_ready,p_ready) %>%
reduce(.f = inner_join, by = c("PIN","DATE"))
pub_join <-
pub %>%
select(-matches("APPR")) # remove these columns to avoid duplicates later
# in_pub_not_p <- anti_join(pub_join,p_join, by = "PIN") # note: the public parcels not found in the master parcel dataset are dropped
not_taxed <-
p_join %>%
filter(TAX_STATUS %!in% "Taxable") %>%
left_join(pub_join, by = c("PIN", "DATE"))
pub_join_other <-
anti_join(pub_join, not_taxed, by = "PIN") %>%
left_join(p_join, by = c("PIN","DATE"))
pub_or_tax_exempt <-
bind_rows(not_taxed, pub_join_other) %>%
filter(!is.na(TAX_REASON))
pub_or_tax_exempt_sf <-
inner_join(pub_or_tax_exempt, p_sf, by = "PIN") %>%
st_as_sf
Step 6
pub_or_tax_exempt_sf_fp <- "./1-data/3-interim/pub_or_tax_exempt_sf_20171013.gpkg"
st_write(pub_or_tax_exempt_sf,dsn = pub_or_tax_exempt_sf_fp, driver = "GPKG")
drive_folder <- as_id("0B5Pp4V6eCkhrZ3NHOEE0Sl9FbWc")
drive_upload(pub_or_tax_exempt_sf_fp, path = drive_folder, name = "pub_or_tax_exempt_sf_20171013.gpkg")