Skip to content

Commit 1e9b6d7

Browse files
authored
Merge pull request #21 from ruralinnovation/development
load_rin_service_areas ETL Refactor
2 parents 5f552f8 + cefdce8 commit 1e9b6d7

22 files changed

Lines changed: 826 additions & 488 deletions

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Imports:
2020
tidyr,
2121
usethis
2222
Roxygen: list(markdown = TRUE)
23-
RoxygenNote: 7.3.2
23+
RoxygenNote: 7.3.3
2424
Depends:
2525
R (>= 3.5)
2626
LazyData: true

NAMESPACE

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# Generated by roxygen2: do not edit by hand
22

3-
export(load_rin_service_areas)
43
importFrom(dplyr,"%>%")
54
importFrom(dplyr,bind_rows)
65
importFrom(dplyr,distinct)

R/archive/old_load_data.R

Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
#' A function to generate RIN service areas (county level) from an XLSX extract from Monday (see params.yml)
2+
#'
3+
#' @param params An object containing values for the $current_year and $monday_network_communities_file_name parameters
4+
#' @param old_rin_service_areas data.frame of previous RIN service areas build
5+
#'
6+
#' @return data.frame of all counties associated with each RIN community
7+
#'
8+
#' @importFrom dplyr %>%
9+
#' @importFrom dplyr bind_rows
10+
#' @importFrom dplyr distinct
11+
#' @importFrom dplyr mutate
12+
#' @importFrom dplyr select
13+
#' @importFrom stats filter
14+
#' @importFrom tidyr separate_rows
15+
load_rin_service_areas <- function (params, old_rin_service_areas) {
16+
17+
# ### OLD ----
18+
19+
# data_file <- "data/RIN Community Service Areas (Updated July 2023) [COPY] - RIN Community Lookup (DO NOT EDIT).csv"
20+
21+
# if (data_uri == "https://docs.google.com/spreadsheets/d/1Qv3nyQ4GrkhIxVs1uEOgN5tfFLtdt_MA71BquPQDGmw" && file.exists(data_file)) {
22+
23+
# message(paste0("Loading ", data_file))
24+
25+
# rin_service_areas_csv <- readr::read_csv(data_file, col_names = TRUE)
26+
27+
# ### TODO: Invert this process so that we always start with Newest data and then fill gaps (missing communities) using previous
28+
29+
# sheet_url <- params$sheet_url
30+
# sheet_name <- params$sheet_name
31+
32+
# # Set up authentication with a service account
33+
# # 1. Create a Google Cloud project
34+
# # 2. Enable the Google Sheets API
35+
# # 3. Create a service account and download JSON key
36+
# # 4. Place the JSON key file in a secure location
37+
38+
# credentials <- Sys.getenv("GOOGLE_API_CREDENTIALS")
39+
40+
# # Point to your service account key file
41+
# googlesheets4::gs4_auth(path = credentials)
42+
43+
# sheet_id <- googlesheets4::as_sheets_id(sheet_url)
44+
45+
# # # Get the sheet names
46+
# all_sheet_names <- googlesheets4::sheet_names(sheet_id)
47+
48+
# stopifnot(sheet_name %in% all_sheet_names)
49+
50+
# sheet_data <- googlesheets4::read_sheet(sheet_url, sheet_name)
51+
52+
# old_rin_data <- sheet_data |>
53+
# dplyr::mutate(
54+
# # `geoid_co` = `geoid_co`,
55+
# # `rin_community` = `rin_community`,
56+
# `primary_county` = paste0(`primary_county_name`, " County, ", state_abbr)
57+
# ) |>
58+
# dplyr::select(
59+
# `geoid_co`,
60+
# `rin_community`,
61+
# `primary_county`
62+
# )
63+
64+
### NEW ----
65+
66+
### RIN data downloaded as of 2025-05-06
67+
#### Monday board: https://ruralinnovation-group.monday.com/boards/6951894369
68+
#### Monday group: Current
69+
#### When downloading new data, run:
70+
# usethis::use_build_ignore(params$monday_network_communities_file_name, escape = TRUE)
71+
72+
# Remove these ghost communities that were never in Monday exports; keep 2023 entries from Google sheet: RIN Community Service Areas (Updated July 2023)
73+
ghost_communities <- c("Grinnell", "Montgomery County", "North Iowa", "Pittsburg")
74+
75+
# Create mapping of community+county → years from package data
76+
# Keep ALL records to preserve year assignments for all counties
77+
old_rin_data_with_years <- old_rin_service_areas |>
78+
sf::st_drop_geometry() |>
79+
dplyr::filter(
80+
!(rin_community %in% ghost_communities & year %in% c(2024, 2025))
81+
) |>
82+
dplyr::select(geoid_co, rin_community, county, year, primary_county_flag)
83+
84+
# Extract just primary counties for recovery loop (existing logic)
85+
old_rin_data <- old_rin_data_with_years |>
86+
dplyr::filter(
87+
`primary_county_flag` == "Yes"
88+
) |>
89+
dplyr::mutate(
90+
`primary_county` = `county`
91+
) |>
92+
dplyr::select(
93+
`geoid_co`,
94+
`rin_community`,
95+
`primary_county`
96+
) |>
97+
dplyr::distinct()
98+
99+
stopifnot(file.exists("data"))
100+
101+
data_dir <- "./data"
102+
103+
### functions ------
104+
get_county_geoid_name_lookup <- function(year = 2024) {
105+
106+
counties <- cori.data::tiger_line_counties(year) |>
107+
sf::st_drop_geometry()
108+
109+
states <- cori.data::tiger_line_states(year) |>
110+
sf::st_drop_geometry()
111+
112+
# state_names <- states %>%
113+
# dplyr::select(GEOID, STUSPS)
114+
115+
county_geoid_name_lookup <- counties |>
116+
dplyr::left_join(
117+
states,
118+
by = c("STATEFP" = "GEOID")
119+
) |>
120+
dplyr::mutate(
121+
name_co = paste0(`NAMELSAD`, ", ", `STUSPS`)
122+
) |>
123+
dplyr::select(geoid_co = `GEOID`, `name_co`) |>
124+
dplyr::distinct()
125+
126+
return(county_geoid_name_lookup)
127+
128+
}
129+
130+
# Load a county geoid_co name_co lookup
131+
county_geoid_name_lookup <- get_county_geoid_name_lookup()
132+
133+
## read in
134+
rin <- readxl::read_excel(paste0(data_dir, "/", params$monday_network_communities_file_name), skip = 2)
135+
136+
names(rin) <- snakecase::to_snake_case(names(rin))
137+
138+
rin_only <- rin |>
139+
dplyr::filter(!is.na(`name`)) |>
140+
dplyr::filter(`name` != "Subitems")
141+
142+
## Check previous data set for additional records not contained in latest Monday extract
143+
for (r in c(1:nrow(old_rin_data))) {
144+
community <- old_rin_data[r, ]
145+
146+
if (community$rin_community %in% rin_only$name) {
147+
print(paste0(r, ": found ", community$rin_community))
148+
} else {
149+
print(paste0(r, ": add ", community$rin_community))
150+
151+
rin_only[(nrow(rin_only) + 1), ] <- data.frame(
152+
matrix(
153+
rep(NA, ncol(rin_only)),
154+
nrow = 1,
155+
dimnames = list(NULL, names(rin_only))
156+
)
157+
) |>
158+
dplyr::mutate(
159+
`name` = community$rin_community,
160+
`primary_county` = community$primary_county
161+
)
162+
163+
print(rin_only[(nrow(rin_only)), ])
164+
}
165+
}
166+
167+
rin_primary_co <- rin_only |>
168+
dplyr::select(
169+
`name`,
170+
`county` = `primary_county`
171+
)
172+
173+
areas <- rin_only |>
174+
dplyr::select(
175+
`name`,
176+
`county` = `other_counties`
177+
) |>
178+
dplyr::filter(
179+
!is.na(`county`)
180+
) |>
181+
tidyr::separate_rows(`county`, sep = "(?<=,\\s[A-Z]{2}),\\s*") |>
182+
dplyr::bind_rows(`rin_primary_co`) |>
183+
dplyr::left_join(county_geoid_name_lookup, by = c('county' = 'name_co')) |>
184+
dplyr::mutate(
185+
`geoid_co` = ifelse(`county` == 'Harrisonburg County, VA', '51660', `geoid_co`),
186+
`geoid_co` = ifelse(`county` == 'Independent City', '51590', `geoid_co`), # Danville city, VA
187+
`geoid_co` = ifelse(`county` == 'Natchitoches County, LA', '22069', `geoid_co`) # Natchitoches Parish, LA
188+
) |>
189+
dplyr::mutate(
190+
primary_county_flag = "No",
191+
data_run_date = Sys.Date()
192+
) |>
193+
dplyr::select(
194+
`geoid_co`,
195+
`rin_community` = `name`,
196+
`county`,
197+
`primary_county_flag`,
198+
`data_run_date`
199+
### THIS IS A BUG! Not all RIN communities in this set are valid for the specified year...
200+
# ) |>
201+
# dplyr::mutate(
202+
# `year` = params$current_year
203+
# )
204+
## ... so, we're going to hand code the list for each year, based on data gathered during
205+
## the compilation of the Impact dashboard dataset; see https://docs.google.com/spreadsheets/d/1R_UccunBsg6TiKD_lAsj37wI5_1H4TKCCd25q914p9U/edit?gid=1698657911#gid=1698657911
206+
###
207+
)
208+
209+
# Build year mapping from preserved package data to preserve existing year assignments
210+
year_mapping <- old_rin_data_with_years |>
211+
dplyr::select(rin_community, county, year_preserved = year) |>
212+
dplyr::distinct()
213+
214+
# Join with year_mapping to preserve years, then apply hardcoded assignments only for NEW communities
215+
areas <- areas |>
216+
dplyr::left_join(
217+
year_mapping,
218+
by = c("rin_community", "county")
219+
) |>
220+
dplyr::mutate(
221+
# Use preserved year if available, otherwise apply hardcoded assignment
222+
year = ifelse(
223+
!is.na(year_preserved),
224+
year_preserved, # Keep existing year from package
225+
ifelse(
226+
# 2026 list...
227+
# ... remaining network communities will need to move up to 2025 list at end-of-year
228+
`rin_community` %in% c( # 2025 list...
229+
"Helena-West Helena, AR",
230+
"Newport, AR"
231+
),
232+
2025,
233+
ifelse(
234+
`rin_community` %in% c( # 2024 list...
235+
"Ada",
236+
"Aberdeen",
237+
"The Berkshires",
238+
"Cape Girardeau",
239+
"Central Wisconsin",
240+
"Chambers County",
241+
"Cochise County",
242+
"The Dalles",
243+
"Durango",
244+
"Eastern Kentucky",
245+
"Emporia",
246+
"Greenfield",
247+
"Independence",
248+
"Indiana County",
249+
"Kirksville",
250+
"Manitowoc County",
251+
"Marquette",
252+
"Nacogdoches",
253+
"NEK",
254+
"Norfolk",
255+
"Paducah",
256+
"Pine Bluff",
257+
"Platteville",
258+
"Portsmouth",
259+
"Pryor Creek",
260+
"Randolph",
261+
"Red Wing",
262+
"Rutland",
263+
"Seward County, NE",
264+
"Shenandoah Valley",
265+
"Springfield",
266+
"Taos",
267+
"Traverse City",
268+
"Waterville",
269+
"Wilkes County",
270+
"Wilson",
271+
"Windham County"
272+
),
273+
2024,
274+
params$current_year # New community not previously in package data
275+
)
276+
)
277+
)
278+
) |>
279+
dplyr::select(-year_preserved) # Remove temp column
280+
281+
check_primary_county <- function (county, rin_community_name, rin_primary_counties) {
282+
283+
primary_county <- (rin_primary_counties |> dplyr::filter(`name` == rin_community_name))$county
284+
285+
if (length(primary_county) > 0) {
286+
if (county %in% primary_county) return("Yes")
287+
else return("No")
288+
} else {
289+
return("No")
290+
}
291+
}
292+
293+
for (r in c(1:nrow(areas))) {
294+
name <- areas[r, ]$rin_community
295+
county <- areas[r, ]$county
296+
297+
areas[r, ]$primary_county_flag <- check_primary_county(county, name, rin_primary_co)
298+
}
299+
300+
# Duplicate records for current_year
301+
302+
# Define communities to EXCLUDE from duplication into current_year cohort
303+
excluded_communities <- c(
304+
"Paso Robles",
305+
"Cedar City",
306+
"Central Wisconsin",
307+
"Platteville",
308+
"Wilkes County",
309+
# Dropped for 2026
310+
"Randolph",
311+
"Liberal",
312+
# Never in network?
313+
# ... from: https://docs.google.com/spreadsheets/d/1Qv3nyQ4GrkhIxVs1uEOgN5tfFLtdt_MA71BquPQDGmw
314+
"Grinnell",
315+
"Montgomery County",
316+
"North Iowa",
317+
"Pittsburg"
318+
)
319+
320+
# Identify which community+county combinations already have year=current_year records
321+
existing_current_year <- areas |>
322+
dplyr::filter(year == params$current_year) |>
323+
dplyr::select(rin_community, county) |>
324+
dplyr::distinct() |>
325+
dplyr::mutate(has_current_year = TRUE)
326+
327+
# Get rows that should be duplicated to current_year
328+
# ONLY duplicate records from the previous year (current_year - 1)
329+
rows_to_duplicate <- areas |>
330+
dplyr::filter(!rin_community %in% excluded_communities) |>
331+
dplyr::filter(year == params$current_year - 1) |> # ONLY previous year
332+
dplyr::left_join(existing_current_year, by = c("rin_community", "county")) |>
333+
dplyr::filter(is.na(has_current_year)) |> # Only rows without existing current_year records
334+
dplyr::select(-has_current_year)
335+
336+
# Create duplicated rows with year set to current_year
337+
areas_current_year <- rows_to_duplicate
338+
areas_current_year$year <- params$current_year
339+
340+
# Combine original data with duplicated rows
341+
areas_updated <- rbind(
342+
areas,
343+
areas_current_year
344+
) |>
345+
dplyr::distinct() |>
346+
dplyr::arrange(`year`)
347+
348+
# } else {
349+
# message("Manually download CSV...")
350+
# message(paste0("From : ", data_uri))
351+
# message(paste0("To : ", data_file))
352+
# message("... then rerun tar_make()")
353+
# }
354+
355+
return(areas_updated |> as.data.frame())
356+
}

0 commit comments

Comments
 (0)