Epidemiological metrics for netdiffuseR#79
Open
aoliveram wants to merge 42 commits into
Open
Conversation
…ion to 1.25.0, and fix exposure rownames issue
…Issue #75) - Add data-raw/epigames.R: bundles epigames_hourly + dynamic_attrs_hourly.csv into epigames list with new $dyn_attrs slot (long format, 201,366 rows) - Add data-raw/epigamesDiffNet.R: collapses hourly attrs to 15 daily windows, populates vertex.dyn.attrs with mask/med/quarantine proportions per day - Regenerate data/epigames.rda and data/epigamesDiffNet.rda Dynamic attributes (mask, med, quarantine) now visible in print(epigamesDiffNet): Dynamic attributes: mask, med, quarantine (3) Validated: exposure(epigamesDiffNet, attrs = 'mask') works with time-varying data. Correlation with static proxy = 0.88, confirming dynamic attrs capture additional temporal variation.
- Removed redundant comments and sanity checks for better readability - Simplified as_diffnet call structure - Regenerated .rda files to match clean scripts
- new_diffnet() gains a -tod- argument (single-behavior vector) with validation (element-wise tod > toa, NA where toa is NA, length match). - When -tod- is supplied, cumadopt is reconstructed from the intervals [toa, tod - 1] via cumadopt_from_intervals() in R/adjmat.r. - New $transmission slot plus exported helpers as_transmission_tree() and get_transmissions() (R/transmission.R) storing the directed infection forest as a data.frame with columns date, source, target, source_exposure_date, virus_id, virus. Docs cite Lloyd-Smith et al. (2005) and White & Pagano (2008). - Tests cover interval reconstruction, validation errors, coercion, and the transmission slot round-trip. No new package dependencies.
Avoid masking epiworldR::get_transmissions() when both packages are loaded. No behavior change; exported name and docs renamed, tests updated accordingly. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds link_fun + link_pars arguments to exposure(). Supported named kernels: identity (default), linear (min(beta*w, 1)), sigmoid (plogis((w-h)/scale)), wells-riley (1 - exp(-beta*w)). Custom user functions are accepted with either signature function(w) or function(w, pars). Non-identity kernels force valued = TRUE with a warning. Default behavior unchanged; 639 pre-existing tests still pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ange weights (M3, #78) Adds four test_that blocks to tests/testthat/test-stochastic-exposure.R covering each link kernel under seconds-scale weights, the degree-denominator fix, and zero-weight self-loop handling. Small code changes in R/stats.R: (1) warn when stochastic mode sees post-kernel weights outside [0, 1] -- the sampler silently saturated before; (2) denominator now counts non-zero-weight neighbours instead of every stored entry, so link kernels that zero out some edges no longer inflate the normaliser. No NAMESPACE / Rd changes. 652 tests pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Drop the dual signature for user-supplied link_fun. The helper now
always calls `link_fun(W@x)` with a single argument; parameters are
expected to be baked into the closure. `link_pars` remains relevant
only for the named kernels ("linear", "sigmoid", "wells-riley").
Simpler API, simpler docs, simpler tests.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds adoption_model = c("threshold", "logit") and adoption_pars
arguments to rdiffnet(). In logit mode, node i adopts at step t with
probability plogis(beta0 + beta_expo * exposure_i), drawn from
runif() each step. Threshold stays the default so fixed-seed calls
that omit the new argument remain bit-identical.
15 new tests cover backward compatibility, parameter validation,
saturation / suppression extremes, and multi-behaviour runs. Full
suite: 665 pass, 0 fail.
…tic/stochastic (M4 follow-up, #78) Renames the two values accepted by adoption_model in rdiffnet() so the vocabulary matches the existing exposure.mode (which already uses deterministic/stochastic). No behavior change: - adoption_model = c("deterministic", "stochastic"), default "deterministic" (was "threshold") - "stochastic" keeps the same plogis(beta0 + beta_expo * exposure) Bernoulli draw previously called "logit" - Error message, roxygen doc and man page updated to match - Test file renamed test-rdiffnet-logit.R -> test-rdiffnet-stochastic.R; all 15 existing expectations updated to use the new names Full suite: 665 passed, 0 failed.
Member
Author
|
The milestones tabla have been updated, following @gvegayon's comments:
Order of execution: M6 → M5 → M7 → M8 → M9 → M10+. |
…M4 -adoption_model = c('deterministic', 'stochastics'). Bumps version 1.25.0 -> 1.26.0
…ix (M6 follow-up, #78)
<noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR adds epidemiological-analysis capabilities to netdiffuseR by extending the core diffnet representation with a canonical multi-cycle state ($status) and an optional transmission-tree layer (diffnet_epi), then building simulation hooks (rdiffnet() + stochastic exposure/adoption/disadoption + lineage tracking) and metrics/tests on top of those primitives.
Changes:
- Introduces
diffnet_epi+ transmission-tree attach/reconstruct/access helpers ($transmission,as_diffnet_epi(),as_transmission_tree(),transmission_tree_from_events()). - Adds multi-cycle diffusion support via a canonical
$statusrepresentation and new accessors (toa()/tod()+ long-formattoa_all()/tod_all()), withnew_diffnet()supportingstatus=. - Extends simulation and exposure tooling: stochastic exposure (
mode="stochastic"), link kernels (link_fun), pluggable adoption mechanisms, disadoption mechanism factories, and optional source attribution (lineage tracking) inrdiffnet().
Reviewed changes
Copilot reviewed 47 out of 55 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| DESCRIPTION | Bumps version and collate order to include new R modules (adoption/disadoption, epi, transmission, accessors). |
| NEWS.md | Notes new stochastic exposure support. |
| NAMESPACE | Exports new epi APIs/metrics and registers new S3 methods. |
| R/adoption_mechanisms.R | Adds pluggable adoption-mechanism kernels (threshold/logit/probit). |
| R/adjmat.r | Adds status-array helpers (status_mat, toa_from_status) and validate_status(). |
| R/data.r | Updates epigamesDiffNet documentation with valued/non-cumulative notes and reconstruction snippet. |
| R/diffnet-class.r | Extends new_diffnet() to accept status= and transmission= and installs canonical $status. |
| R/diffnet-epi.R | Implements diffnet_epi subclass promotion, printing, and reconstruction via attribution. |
| R/diffnet-indexing.r | Keeps $status synchronized with $cumadopt during subsetting. |
| R/disadoption_mechanisms.R | Adds disadoption-mechanism factories (random/bithreshold/logit/probit). |
| R/random_graph.R | Keeps $status synchronized with $cumadopt in graph generators. |
| R/rdiffnet.r | Adds stochastic exposure mode, adoption mechanism plug-in, disadoption-aware status construction, and lineage tracking via source attribution. |
| R/rewire.r | Keeps $status synchronized with $cumadopt during rewiring. |
| R/source_attribution.R | Adds source-attribution kernels + normalization + tree-row assembly helper. |
| R/stats.R | Extends exposure() with stochastic mode + link kernels; updates hazard-rate to use $status. |
| R/status_accessors.R | Adds toa/tod and long-format toa_all/tod_all accessors built on $status. |
| R/transmission.R | Adds transmission-tree schema, attach/access helpers, and post-hoc reconstruction from events. |
| data-raw/epigames.R | Adds hourly dynamic attributes ingestion and bundles into epigames. |
| data-raw/epigamesDiffNet.R | Rebuilds epigamesDiffNet as daily, valued, non-cumulative and reconstructs a tree via attribution. |
| man/adoption_mechanisms.Rd | Documents adoption mechanisms. |
| man/as_transmission_tree.Rd | Documents as_transmission_tree(). |
| man/diffnet-class.Rd | Documents new new_diffnet() args (status, transmission, transmission_pars). |
| man/diffnet_epi.Rd | Documents diffnet_epi, promotion, and print behavior. |
| man/disadoption_mechanisms.Rd | Documents disadoption mechanisms. |
| man/epigamesDiffNet.Rd | Documents valued/non-cumulative semantics and reconstruction snippet. |
| man/exposure.Rd | Documents mode, link_fun, and link_pars additions. |
| man/generation_time.Rd | Documents generation_time() metric. |
| man/peak_prevalence.Rd | Documents peak_prevalence() / peak_time(). |
| man/rdiffnet.Rd | Documents new rdiffnet() args (exposure.mode, mechanisms, source attribution). |
| man/repr_number.Rd | Documents repr_number() metric and plot/print methods. |
| man/secondary_attack_rate.Rd | Documents secondary_attack_rate() metric. |
| man/source_attribution.Rd | Documents source-attribution kernels. |
| man/status_accessors.Rd | Documents status-based accessors. |
| man/summary.diffnet_epi.Rd | Documents summary.diffnet_epi() extension block. |
| man/survival_curve.Rd | Documents survival_curve() metric and print method. |
| man/transmission_tree.Rd | Documents transmission_tree() accessor. |
| man/transmission_tree_from_events.Rd | Documents post-hoc tree reconstruction primitive. |
| man-roxygen/graph_template.R | Hardens roxygen template logic for parameter inclusion. |
| tests/testthat/test-cumulative_adopt_count.R | Adds hazard-rate regression for non-monotone status. |
| tests/testthat/test-diffnet-epi.R | Adds promotion/printing/inheritance tests for diffnet_epi. |
| tests/testthat/test-diffnet-methods.R | Adds plot_adopters() regression for non-monotone status. |
| tests/testthat/test-epi-metrics.R | Adds end-to-end tests for peak/survival/SAR/gen-time/R and summary block. |
| tests/testthat/test-exposure-link-fun.R | Adds kernel/link-function tests for exposure. |
| tests/testthat/test-rdiffnet-cross-coupling.R | Tests per-behaviour dispatch + cross-state visibility in adoption mechanism. |
| tests/testthat/test-rdiffnet-disadoption.R | Tests disadoption mechanisms + composition and regressions. |
| tests/testthat/test-rdiffnet-source-attribution.R | Tests source attribution kernels and lineage tracking behavior. |
| tests/testthat/test-rdiffnet-stochastic.R | Tests stochastic adoption mechanisms and user plug-ins. |
| tests/testthat/test-status-slot.R | Tests canonical $status semantics, constructor behavior, and accessors. |
| tests/testthat/test-stochastic-exposure.R | Tests stochastic exposure behavior, weighting, and bounds. |
| tests/testthat/test-transmission.R | Tests transmission-tree attach/access/validation and reconstruction agreement. |
Files not reviewed (6)
- man/adoption_mechanisms.Rd: Generated file
- man/as_transmission_tree.Rd: Generated file
- man/diffnet-class.Rd: Generated file
- man/diffnet_epi.Rd: Generated file
- man/disadoption_mechanisms.Rd: Generated file
- man/epigamesDiffNet.Rd: Generated file
Comment on lines
+616
to
+617
| if (any(!status %in% c(0L, 1L, NA_integer_, 0, 1))) | ||
| stop("-status- entries must be 0 or 1.") |
Comment on lines
+631
to
+632
| if (any(!status[[q]] %in% c(0L, 1L, NA_integer_, 0, 1))) | ||
| stop("-status[[", q, "]]- entries must be 0 or 1.") |
Comment on lines
+101
to
+105
| src <- suppressWarnings(as.integer(tree$source)) | ||
| src_ok <- src[!is.na(src)] | ||
| if (length(src_ok) && (any(src_ok < 1L) || any(src_ok > n))) | ||
| stop("-tree$source- must be NA or an integer index in 1..", n, ".") | ||
|
|
Comment on lines
+69
to
+74
| if (is.null(s)) { | ||
| # Defensive — every diffnet built post-status-refactor has a $status | ||
| # slot, but keep this safe against any older object that might still | ||
| # be in scope. | ||
| return(rep(NA_integer_, length(x$toa))) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #78.
This draft PR tracks the implementation of epidemiological analysis capabilities in
netdiffuseR, addressing the four gaps identified in the internal gap report:tod) / reinfection episodes.stochastic-transmissionbranch, now integrated here).This branch starts from
masterand has already integrated two upstream feature branches:issue-75-epigames-dynamic-attrs— dynamic behavioral attributes for Epigames.stochastic-transmission—mode = "stochastic"forexposure()/rdiffnet().No new dependencies will be added to
DESCRIPTION.Implementation milestones
\$todslot,\$transmissionslot, validators, coercionsR/diffnet-class.r,R/adjmat.r, newR/transmission.Rlink_funinexposure()R/stats.Rtests/testthat/adoption_model = \"logit\"inrdiffnet()R/rdiffnet.rR/epi_metrics.Rhazard_rate(),plot_adopters()under\$todR/stats.R,R/diffnet-methods.rrepr_number()+ plot methodR/epi_metrics.Rhistories.csv → \$transmissiondata-raw/vignettes/epidemiological-analysis.Rmdtests/testthat/,.github/workflows/