Skip to content

Commit 7e76378

Browse files
Merge pull request #233 from canmod/change-names
Change names
2 parents 2b35fd5 + cd0ce1c commit 7e76378

File tree

9 files changed

+59
-13
lines changed

9 files changed

+59
-13
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: macpan2
22
Title: Fast and Flexible Compartmental Modelling
3-
Version: 1.13.0
3+
Version: 1.14.0
44
Authors@R: c(
55
person("Steve Walker", email="swalk@mcmaster.ca", role=c("cre", "aut")),
66
person("Weiguang Guan", role="aut"),

R/change_models.R

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@
22
ChangeModelDefaults = function() {
33
self = ChangeModel()
44

5+
self$change_list = list()
6+
57
self$flow_frame = function() {
6-
## TODO: check for change_list
7-
(self$change_list
8+
cl = self$change_list
9+
if (length(cl) == 0L) return(self$empty_flow_frame)
10+
(cl
811
|> method_apply("flow_frame")
912
|> bind_rows()
1013
)
1114
}
1215
self$change_frame = function() {
13-
(self$change_list
16+
cl = self$change_list
17+
if (length(cl) == 0L) return(self$empty_change_frame)
18+
(cl
1419
|> method_apply("change_frame")
1520
|> bind_rows()
1621
)
@@ -46,5 +51,20 @@ ChangeModelDefaults = function() {
4651
|> unique()
4752
)
4853
}
54+
self$duplicated_change_names = function() {
55+
frame = self$flow_frame()
56+
dups = frame$change[duplicated(frame$change)]
57+
return(dups)
58+
}
59+
self$check = function() {
60+
dups = self$duplicated_change_names()
61+
if (length(dups) > 0L) {
62+
stop(
63+
"The following names are duplicates:\n "
64+
, paste(dups, collapse = " \n")
65+
)
66+
}
67+
NULL
68+
}
4969
return_object(self, "ChangeModelDefaults")
5070
}

R/formula_list_generators.R

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,20 @@ ChangeModel = function() {
9090
# list of formula expressions to be added to an `after` list
9191
self$after_loop = function() list()
9292

93+
self$empty_flow_frame = empty_frame("size", "change", "rate", "abs_rate")
94+
self$empty_change_frame = empty_frame("state", "change")
95+
9396
# one row per flow
9497
# size : aka name of the from compartment
9598
# change : absolute flow rate name
9699
# rate : string with expression for the per-capita flow rate
97100
# abs_rate : string with expression for the absolute flow rate
98-
self$flow_frame = function() empty_frame("size", "change", "rate", "abs_rate")
101+
self$flow_frame = function() self$empty_flow_frame
99102

100103
# one row per term in a state update expression
101104
# state : name of the state being updated
102105
# change : string with the term in the expression that updates that state
103-
self$change_frame = function() empty_frame("state", "change")
106+
self$change_frame = function() self$empty_change_frame
104107

105108
# character vector of ChangeComponent class names used in the model
106109
self$change_classes = function() character()
@@ -264,7 +267,7 @@ SimpleChangeModel = function(before = list(), during = list(), after = list()) {
264267
}
265268
self$before_loop = function() self$before
266269
self$after_loop = function() self$after
267-
270+
self$check()
268271
return_object(self, "SimpleChangeModel")
269272
}
270273

@@ -278,6 +281,7 @@ AllFormulaChangeModel = function(before = list(), during = list(), after = list(
278281
self$before_flows = function() self$during
279282
self$after_loop = function() self$after
280283

284+
self$check()
281285
return_object(self, "AllFormulaChangeModel")
282286
}
283287

@@ -489,13 +493,21 @@ get_change_model = function(before, during, after) {
489493
AllFormulaChangeModel(before, during, after)
490494
}
491495
force_expr_list = function(x) {
496+
is_change_component = function(x) inherits(x, "ChangeComponent")
497+
is_valid = function(x) isTRUE(is_two_sided(x) | is_change_component(x))
492498
if (is_two_sided(x)) return(list(x))
493-
if (inherits(x, "ChangeComponent")) return(list(x))
499+
if (is_change_component(x)) return(list(x))
494500
if (!is.list(x)) {
495-
## TODO: should make more sense!
501+
## TODO: msg should make more sense to humans
496502
stop("Argument must be a formula, change component, or a list of such objects.")
497503
}
498-
## TODO: check that we have a list of valid components
504+
invalid = !vapply(x, is_valid, logical(1L))
505+
if (any(invalid)) {
506+
stop(
507+
"The expressions at the following positions are invalid: "
508+
, paste(which(invalid), collapse = ", ")
509+
)
510+
}
499511
return(x)
500512
}
501513

R/tmb_model_editors.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ mp_tmb_insert = function(model
8686
model = assert_cls(model, "TMBModelSpec", match.call(), "?mp_tmb_model_spec")
8787
valid$char1$check(phase)
8888
at = valid$num1$assert(at)
89+
expressions = force_expr_list(expressions)
8990

9091
model = model$copy()
9192
model[[phase]] = append(model[[phase]], expressions, after = at - 1L)
@@ -124,6 +125,7 @@ mp_tmb_update = function(model
124125
model = assert_cls(model, "TMBModelSpec", match.call(), "?mp_tmb_model_spec")
125126
valid$char1$check(phase)
126127
at = valid$num1$assert(at)
128+
expressions = force_expr_list(expressions)
127129

128130
model = model$copy()
129131
where = at - 1L + seq_along(expressions)

README.Rmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ repos = c('https://canmod.r-universe.dev', 'https://cloud.r-project.org')
4747
install.packages('macpan2', repos = repos)
4848
```
4949

50-
This command will install the current version of `macpan2`. For projects in production that need to keep track of specific versions of `macpan2`, snapshots and other reproducibility information can be obtained [here](https://canmod.r-universe.dev/api). Please see [this article](https://ropensci.org/blog/2022/01/06/runiverse-renv/) for an explanation of how to manage reproducibility using `r-universe`.
50+
This command will install the current version of `macpan2`. For projects in production that need to keep track of specific versions of `macpan2`, snapshots and other reproducibility information can be obtained [here](https://canmod.r-universe.dev/apis). Please see [this article](https://ropensci.org/blog/2022/01/06/runiverse-renv/) for an explanation of how to manage reproducibility using `r-universe`.
5151

5252
To get the latest development version of `macpan2`, or if the above command fails for some reason, an alternative command to install is the following.
5353
```

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ library(dplyr)
149149
|> mp_simulator(time_steps = 50, outputs = c("I", "infection"))
150150
|> mp_trajectory()
151151
|> mutate(quantity = case_match(matrix
152-
, "I" ~ "Prevalance"
152+
, "I" ~ "Prevalence"
153153
, "infection" ~ "Incidence"
154154
))
155155
|> ggplot()

man/figures/plot-tmb-si-1.png

-18 Bytes
Loading

tests/testthat/test-repeat-flows.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
test_that("repeated flow names get flagged", {
2+
expect_error(
3+
mp_tmb_model_spec(
4+
during = list(
5+
mp_per_capita_flow("S", "I", "beta * I", "repeated_flow_name")
6+
, mp_per_capita_flow("I", "R", "gamma" , "repeated_flow_name")
7+
)
8+
, default = list(S = 1 - 1e-5, I = 1e-5, beta = 0.25, gamma = 0.1)
9+
)
10+
, "The following names are duplicates"
11+
)
12+
})

vignettes/calibration_advanced.Rmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ fit <- sir_simulator$optimize$nlminb()
622622

623623
Here is a reasonably difficult problem -- fit an SIR model to weekly measles incidence data from London UK over about six decades.
624624

625-
<!-- FIXME: store data locally, don't rely on IIDA ... -->
625+
<!-- FIXME: store data locally, don't rely on IIDDA ... -->
626626
```{r sir_plot, fig.width=6}
627627
measles = read.csv(
628628
file.path(

0 commit comments

Comments
 (0)