Skip to content

Commit 8e5f84b

Browse files
authored
[PR-11] Output formats, dev infra, final polish
Final polish PR for the neoipcr upstreaming stack: - `write_json()` for plain-JSON neoipcr interchange (minimum subset); promotes `jsonlite` to Imports. - Deprecated-API sweep: `dplyr::case_match()` → `dplyr::recode_values()`; fix tidyselect `.data\$` usage. - Real-data fixes: NA-safe `drop_quartiles` gate; VRE genus filter; split `unknownPathogenNames` before `finalize_to_schema` strips `name`. - Adopt `data/` as the protected local-only directory convention (was `data/local/`); mechanical safeguards via `.gitignore` + `.Rbuildignore`. - Universal-tier guardrails: doc-comments in-band (not as a sweep), namespace-qualification, plus 8 others. - WIP `API-DESIGN.md` checked in as a living draft.
1 parent a03e411 commit 8e5f84b

22 files changed

Lines changed: 1444 additions & 108 deletions

.Rbuildignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
^\.Rproj\.user$
66
^LICENSE\.md$
77
^README\.Rmd$
8+
^data$
89
^data-raw$
910
^tools$
1011
^\.covrignore$
1112
^CLAUDE\.md$
13+
^API-DESIGN\.md$
1214
^coverage\.html$
1315
^lib$
1416
^scripts$

.github/copilot-instructions.md

Lines changed: 15 additions & 4 deletions
Large diffs are not rendered by default.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,6 @@ rsconnect/
5757
# Local coverage report
5858
coverage.html
5959
lib/
60+
61+
# Local-only sensitive data (the protected-dir convention)
62+
data/

API-DESIGN.md

Lines changed: 1092 additions & 0 deletions
Large diffs are not rendered by default.

CLAUDE.md

Lines changed: 15 additions & 4 deletions
Large diffs are not rendered by default.

DESCRIPTION

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ LazyData: true
1717
Roxygen: list(markdown = TRUE)
1818
Depends:
1919
R (>= 4.4)
20-
Imports:
20+
Imports:
2121
askpass (>= 1.2.1),
2222
dplyr (>= 1.1.4),
2323
httr2 (>= 1.1.1),
2424
ids (>= 1.0.1),
25+
jsonlite (>= 1.9.1),
2526
lubridate (>= 1.9.4),
2627
purrr (>= 1.0.4),
2728
readr (>= 2.1.5),
@@ -33,7 +34,6 @@ Imports:
3334
uuid (>= 1.2-1)
3435
Suggests:
3536
covr (>= 3.6.0),
36-
jsonlite (>= 1.9.1),
3737
roxygen2 (>= 8.0.0),
3838
testthat (>= 3.0.0),
3939
withr (>= 2.5.0),
@@ -67,6 +67,7 @@ Collate:
6767
'import-dhis2.R'
6868
'import-standalone-obj-type.R'
6969
'import-standalone-types-check.R'
70+
'json.R'
7071
'neoipcr-package.R'
7172
'pathogens.R'
7273
'scales.R'

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,6 @@ export(is_valid_ichi_code)
2727
export(neoipc_poisson_ci)
2828
export(neoipc_wilson_ci)
2929
export(pretty_names)
30+
export(write_json)
3031
import(rlang)
3132
importFrom(rlang,.data)

R/calc-api.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -854,15 +854,15 @@ pretty_names.neoipcr_tbl_sr_ref <- function(x, ...) {
854854
dplyr::inner_join(pairs, dplyr::join_by("pro_cat")) |>
855855
dplyr::mutate(pro_cat = .data$pretty_name, .keep = "unused") |>
856856
dplyr::rename_with(
857-
~ dplyr::case_match(
857+
~ dplyr::recode_values(
858858
.x,
859859
"pro_cat"~col_names[["pro_cat"]],
860860
"n"~col_names[["n"]],
861861
"pooled"~col_names[["pooled"]],
862862
"q1"~col_names[["q1"]],
863863
"q2"~col_names[["q2"]],
864864
"q3"~col_names[["q3"]],
865-
.default = .x))
865+
default = .x))
866866
}
867867

868868
quartile_probs <- c(0.25,0.5,0.75)

R/calc-procedure-categories.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ get_procedure_category <- function(x, not_surgery_na = FALSE) {
210210
}
211211

212212
get_procedure_category_pretty <- function(x) {
213-
dplyr::case_match(
213+
dplyr::recode_values(
214214
as.character(x),
215215
"overall" ~ gettext("Overall"),
216216
"abdominal_surgery" ~ gettext("Abdominal surgery"),
@@ -222,6 +222,6 @@ get_procedure_category_pretty <- function(x) {
222222
"other" ~ gettext("Other"),
223223
"not_surgery" ~ gettext("Not a surgical procedure"),
224224
"to_be_categorised" ~ gettext("Not yet categorised"),
225-
.default = x
225+
default = x
226226
)
227227
}

R/calc-rates.R

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ get_dev_ass_incidence_density_rates <- function(
1717
dplyr::select("event_key", "dev_ass") |>
1818
dplyr::filter(.data$dev_ass != 0) |>
1919
dplyr::mutate(
20-
dev = dplyr::case_match(
20+
dev = dplyr::recode_values(
2121
as.integer(as.character(.data$dev_ass)),
2222
!!!dev_map),
2323
.keep = "unused")
@@ -144,7 +144,9 @@ get_infectious_agent_detection_rates_with_department_quartiles <- function(
144144
use_cache = use_cache) |>
145145
dplyr::select(tidyselect::all_of(c(group_cols, "n", "inf_with_pathogen")), rate = "n_per_iwp") |>
146146
dplyr::mutate(
147-
drop_quartiles = n_deps < 5 | round(100 / .data$rate) >= median_inf_with_pathogen)
147+
drop_quartiles = tidyr::replace_na(
148+
n_deps < 5 | round(100 / .data$rate) >= median_inf_with_pathogen,
149+
TRUE))
148150

149151
if(nrow(r1) < 1)
150152
{
@@ -427,7 +429,7 @@ get_resistance_test_rate_with_department_quartiles <- function(
427429
na.rm = TRUE)) |>
428430
dplyr::mutate(
429431
name=names(.data$value),
430-
name=dplyr::case_match(
432+
name=dplyr::recode_values(
431433
.data$name,
432434
"25%"~"q1",
433435
"50%"~"q2",
@@ -445,7 +447,9 @@ get_resistance_test_rate_with_department_quartiles <- function(
445447

446448
rate <- rate |>
447449
dplyr::mutate(
448-
drop_quartiles = .data$n_deps < 5 | round(100 / .data$rate) >= .data$median,
450+
drop_quartiles = tidyr::replace_na(
451+
.data$n_deps < 5 | round(100 / .data$rate) >= .data$median,
452+
TRUE),
449453
q1 = dplyr::if_else(
450454
.data$drop_quartiles,
451455
NA,
@@ -518,7 +522,7 @@ get_resistance_test_rate <- function(
518522
dplyr::across(
519523
tidyselect::all_of(resistance),
520524
~ factor(
521-
dplyr::case_match(
525+
dplyr::recode_values(
522526
as.character(.x),
523527
"yes" ~ "tested",
524528
"no" ~ "tested",
@@ -609,7 +613,7 @@ get_resistance_rate_with_department_quartiles <- function(
609613
na.rm = TRUE)) |>
610614
dplyr::mutate(
611615
name=names(.data$value),
612-
name=dplyr::case_match(
616+
name=dplyr::recode_values(
613617
.data$name,
614618
"25%"~"q1",
615619
"50%"~"q2",
@@ -628,7 +632,9 @@ get_resistance_rate_with_department_quartiles <- function(
628632

629633
rate <- rate |>
630634
dplyr::mutate(
631-
drop_quartiles = .data$n_deps < 5 | round(100 / .data$inf_rs_rate) >= .data$median,
635+
drop_quartiles = tidyr::replace_na(
636+
.data$n_deps < 5 | round(100 / .data$inf_rs_rate) >= .data$median,
637+
TRUE),
632638
q1 = dplyr::if_else(
633639
.data$drop_quartiles,
634640
NA,
@@ -721,7 +727,7 @@ get_organism_resistance_rate_with_department_quartiles <- function(
721727
na.rm = TRUE)) |>
722728
dplyr::mutate(
723729
name=names(.data$value),
724-
name=dplyr::case_match(
730+
name=dplyr::recode_values(
725731
.data$name,
726732
"25%"~"q1",
727733
"50%"~"q2",
@@ -740,7 +746,9 @@ get_organism_resistance_rate_with_department_quartiles <- function(
740746

741747
rate <- rate |>
742748
dplyr::mutate(
743-
drop_quartiles = .data$n_deps < 5 | round(100 / .data$ia_rs_rate) >= .data$median,
749+
drop_quartiles = tidyr::replace_na(
750+
.data$n_deps < 5 | round(100 / .data$ia_rs_rate) >= .data$median,
751+
TRUE),
744752
q1 = dplyr::if_else(
745753
.data$drop_quartiles,
746754
NA,

0 commit comments

Comments
 (0)