-
Notifications
You must be signed in to change notification settings - Fork 37
Refactor estimate_truncation to use S3 class pattern #1221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Rename obs → observations, data → args. Remove last_obs and cmf elements. Co-authored-by: sbfnk-bot <[email protected]>
Co-authored-by: sbfnk-bot <[email protected]>
Co-authored-by: sbfnk-bot <[email protected]>
Co-authored-by: sbfnk-bot <[email protected]>
Co-authored-by: sbfnk-bot <[email protected]>
Co-authored-by: sbfnk-bot <[email protected]>
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThe pull request converts estimate_truncation() to a formal S3 object (class "estimate_truncation", "epinowfit"), replacing legacy list fields with components Changes
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
d97f2cf to
a948b41
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Fix all issues with AI Agents 🤖
In @R/estimate_truncation.R:
- Around line 329-341: The deprecated field handler in estimate_truncation()
maps old names to new ones but then calls NextMethod("$"), which looks up the
original (now-missing) name and returns NULL; instead, after calling
lifecycle::deprecate_warn for names in deprecated_map (obs/data), directly
return the value from the new field (use deprecated_map[[name]] to index the
object and return its contents) so est$obs and est$data continue to return
est$observations and est$args during the deprecation period rather than NULL.
- Around line 371-383: The `[[` method in estimate_truncation uses
NextMethod("[[") which forwards the old (deprecated) name that no longer exists;
update the call to forward the new name from deprecated_map instead (use the
mapped value, e.g. pass i = deprecated_map[[i]] to NextMethod) so the next
method receives the current field name; locate the deprecated_map and the
estimate_truncation `[[` method and replace the plain NextMethod call with one
that supplies the renamed field.
🧹 Nitpick comments (3)
NEWS.md (1)
44-45: Consider consolidating repeated guidance aboutget_delay()for clarity.Lines 44 and 45 both instruct users to use
get_delay(object). Whilst line 45 adds context about downstream usage inepinow(), the repetition could be tightened. Consider merging the removal explanation and the usage guidance into a single instruction for improved readability.man/get_delay.Rd (2)
22-24: Clarify terminology and consider lifecycle consistency across estimate_truncation accessors.The function is marked "experimental" (line 22), which is appropriate for a new public API. However,
get_samples.estimate_truncation(documented in man/get_samples.Rd) would inherit the "Stable" lifecycle from its generic. This creates asymmetry in user messaging about API maturity for the two primary estimate_truncation accessors.Additionally, the description (line 24) could be more explicit: "delay" is overloaded in EpiNow2 (reporting delay, generation time, truncation delay). Clarifying that this extracts the truncation delay distribution would improve clarity for new users.
26-31: Example is adequate but could show expected output.The example demonstrates the main usage pattern (extracting the distribution for use in
trunc_opts()), which is helpful. For an experimental function, this level of documentation is acceptable. Optional enhancement: show whatget_delay(est)returns (adist_specobject) to help users understand the output format and structure.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
NAMESPACENEWS.mdR/estimate_truncation.RR/get.RR/summarise.Rman/estimate_truncation.Rdman/get_delay.Rdman/get_samples.Rdman/summary.estimate_truncation.Rdtests/testthat/test-estimate_truncation.R
🧰 Additional context used
📓 Path-based instructions (4)
R/**/*.R
📄 CodeRabbit inference engine (CLAUDE.md)
R/**/*.R: Deprecate functionality using the{lifecycle}package. Follow the deprecation lifecycle: Warning withlifecycle::deprecate_warn(), then Stopping withlifecycle::deprecate_stop(), then Removal. Add lifecycle badge to documentation using#' @descriptionr lifecycle::badge('deprecated')`
Use roxygen2 with Markdown syntax for documentation
Use sentence case for roxygen2 function titles, not title case. Good: 'Calculate confidence intervals'. Bad: 'Calculate Confidence Intervals'
Files:
R/get.RR/summarise.RR/estimate_truncation.R
{R/**/*.R,tests/**/*.R}
📄 CodeRabbit inference engine (CLAUDE.md)
Follow the tidyverse style guide. Limit lines to 80 characters for code and comments. Use styler package to apply styles. Don't restyle code unrelated to your changes.
Files:
R/get.Rtests/testthat/test-estimate_truncation.RR/summarise.RR/estimate_truncation.R
tests/testthat/test-*.R
📄 CodeRabbit inference engine (CLAUDE.md)
tests/testthat/test-*.R: Make test descriptions descriptive but brief using patterns like 'works as expected with default arguments', 'errors for bad X specifications', 'produces expected output', 'correctly handles X'
Use testthat for unit tests
Files:
tests/testthat/test-estimate_truncation.R
NEWS.md
📄 CodeRabbit inference engine (CLAUDE.md)
Add a NEWS.md item for user-facing changes before opening a PR. Describe user-facing changes, never reference issues or PRs. Start with action verbs: 'Added', 'Fixed', 'Updated', 'Changed'
Files:
NEWS.md
🧠 Learnings (2)
📚 Learning: 2025-12-19T15:41:21.706Z
Learnt from: CR
Repo: epiforecasts/EpiNow2 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T15:41:21.706Z
Learning: Applies to tests/testthat/test-*.R : Make test descriptions descriptive but brief using patterns like 'works as expected with default arguments', 'errors for bad X specifications', 'produces expected output', 'correctly handles X'
Applied to files:
tests/testthat/test-estimate_truncation.R
📚 Learning: 2025-12-19T15:41:21.706Z
Learnt from: CR
Repo: epiforecasts/EpiNow2 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-19T15:41:21.706Z
Learning: Applies to NEWS.md : Add a NEWS.md item for user-facing changes before opening a PR. Describe user-facing changes, never reference issues or PRs. Start with action verbs: 'Added', 'Fixed', 'Updated', 'Changed'
Applied to files:
NEWS.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: ubuntu-latest (oldrel-1)
- GitHub Check: windows-latest (release)
- GitHub Check: ubuntu-latest (release)
- GitHub Check: macOS-latest (release)
- GitHub Check: ubuntu-latest (devel)
- GitHub Check: lint-changed-files
- GitHub Check: test-coverage
- GitHub Check: pkgdown
- GitHub Check: R-CMD-as-cran-check
- GitHub Check: document
🔇 Additional comments (17)
NEWS.md (1)
42-48: News entry follows guidelines and is well-structured.The changelog entry appropriately documents user-facing breaking changes and new accessors with clear action-verb language, no PR/issue references, and helpful examples. The deprecation guidance is explicit.
man/get_samples.Rd (1)
9-9: Documentation addition is correct.The new
\alias{get_samples.estimate_truncation}and method signature are properly added and follow the established pattern for other S3 method variants in this file.Also applies to: 22-22
NAMESPACE (1)
6-6: LGTM!The auto-generated NAMESPACE correctly exports the new
get_delaygeneric and registers all the new S3 methods for theestimate_truncationclass ($,[[,get_delay,get_samples,summary). These additions align with the PR objectives to introduce an S3 class pattern.Also applies to: 10-10, 18-18, 25-25, 48-48, 94-94
man/summary.estimate_truncation.Rd (1)
1-37: LGTM!The documentation correctly describes the new
summary.estimate_truncation()method with appropriate type options, follows sentence case for the title as per coding guidelines, and includes accurate return value descriptions for each type.R/get.R (2)
256-304: LGTM!The
get_delay()generic andget_delay.estimate_truncation()method correctly extract the fitted delay parameters, construct Normal distributions for each parameter to represent posterior uncertainty, and return a properly formatteddist_spec. The experimental lifecycle badge is appropriate for this new API.
385-427: LGTM!The
get_samples.estimate_truncation()method correctly extracts posterior samples for delay parameters and reconstructed observations, combining them into a consistent format with the expected columns. The use ofrbindlist(..., fill = TRUE)properly handles differing column sets between delay parameters and reconstructed observations.R/summarise.R (1)
988-1039: LGTM!The
summary.estimate_truncation()method is well-implemented with clean dispatch based on thetypeargument. It correctly delegates toget_delay()for the distribution, directly accessesobject$observationsfor observations data, and usescalc_summary_measures()for parameter summaries. The use ofarg_match()ensures robust type validation.tests/testthat/test-estimate_truncation.R (4)
22-29: LGTM!The core test correctly validates the new return structure (
observations,args,fit) and exercises the new accessors (get_delay(),summary(type = "dist"), andest$observations). Test descriptions follow the recommended patterns.
44-49: LGTM!The cmdstanr backend variant test is appropriately updated to validate the same new structure and
get_delay()accessor.
71-84: LGTM!The filter_leading_zeros test correctly validates the new names and uses
get_delay()to compare truncation distributions between fits. Accessing$diston the returneddist_specobject (lines 77-78) and$args$obs_dist(lines 81-82) is appropriate for comparison.
97-99: LGTM!The zero_threshold test is correctly updated to expect the new structure names and validate
get_delay()returns adist_spec.man/estimate_truncation.Rd (2)
62-77: LGTM!The return value documentation clearly describes the new
estimate_truncationobject structure withobservations,args, andfitcomponents. The guidance to useget_delay()for extracting the truncation distribution and the listing of available S3 methods is helpful for users.
128-145: LGTM!The examples are correctly updated to demonstrate the new API patterns:
get_delay(est),summary(est, type = "dist"),est$observations, andtrunc_opts(get_delay(est)).R/estimate_truncation.R (4)
55-68: LGTM!The roxygen documentation accurately describes the new return structure and available S3 methods, following the coding guidelines for roxygen2 with Markdown syntax.
214-217: LGTM!Storing
dist_typeanddist_maxinstan_data(which becomesout$args) enablesget_delay()to reconstruct thedist_specwith the fitted posterior parameters. This is a clean approach to preserve the distribution metadata needed for the accessor.
261-264: LGTM!The output structure correctly uses the new naming conventions (
observationsinstead ofobs,argsinstead ofdata) as specified in the PR objectives, aligning with theestimate_infections()pattern.
288-313: LGTM!The plot method is correctly updated to access
x$observations(the renamed field) and passes it appropriately to the ggplot components.
… into refactor/estimate-truncation-s3
1f8683c to
b69669c
Compare
get_delays() now always returns a named list of dist_spec objects, providing a consistent return type. It extracts posterior estimates when delay parameters were estimated (prior_sd > 0), otherwise returns fixed values or priors. Co-authored-by: sbfnk-bot <[email protected]>
Tests 5 scenarios for delay parameter naming: - Single parametric delay - Nonparametric followed by parametric (bug #1236 pattern) - Two parametric delays - Parametric followed by nonparametric - Three delay types with mixed parametric/nonparametric Co-authored-by: sbfnk-bot <[email protected]>
Remove workaround code that checked for either reporting[2] or truncation[1] since parameters are now always named correctly. Also removes the redundant regression test as this is now covered by unit tests in test-delays.R. Co-authored-by: sbfnk-bot <[email protected]>
Reduces the function from 24 lines to 3 by reusing the existing reconstruct_delay helper that handles parameter extraction. Co-authored-by: sbfnk-bot <[email protected]>
Moves data munging logic from estimate_truncation into a separate internal function for better testability and code organisation. Co-authored-by: sbfnk-bot <[email protected]>
Replace NextMethod() with .subset2() in $ and [[ methods for estimate_truncation. NextMethod doesn't work correctly for list-based S3 objects and can return NULL instead of the element. Co-authored-by: sbfnk-bot <[email protected]>
- Add unit tests for prepare_truncation_obs helper function - Add parameter recovery test verifying estimated truncation params match true values (meanlog ~ 0.9, sdlog ~ 0.6) - Refactor tests to reuse single MCMC fit for better performance Co-authored-by: sbfnk-bot <[email protected]>
Co-authored-by: sbfnk-bot <[email protected]>
… into refactor/estimate-truncation-s3
- Fix obs_dist length expectation (3 datasets = 3 values) - Replace parameter recovery test with structural test for dist_spec since MCMC with short chains doesn't reliably recover true params Co-authored-by: sbfnk-bot <[email protected]>
… into refactor/estimate-truncation-s3
Provides a cleaner interface for extracting a single delay distribution: get_delay(fit, "truncation") instead of: get_delays(fit)$truncation Co-authored-by: sbfnk-bot <[email protected]>
Since estimate_truncation inherits from epinowfit and sets up delay_id_truncation in args, the epinowfit method works correctly. Co-authored-by: sbfnk-bot <[email protected]>
Uses longer chains (4 chains, 2000 iter) to verify that estimated truncation parameters are close to true values used to generate example_truncated (meanlog ~ 0.9, sdlog ~ 0.6). Co-authored-by: sbfnk-bot <[email protected]>
Update seealso to reference get_delays() instead of the removed get_delays.estimate_truncation() method. Co-authored-by: sbfnk-bot <[email protected]>
seabbs
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good. I think ideally get_delay would be used in the example and vignette vs get_delays and there was instance I was expecting to see a internal function based on the review responses but didn't.
- Add merge_predictions_obs() internal helper to deduplicate observation processing code in plot.estimate_truncation and deprecated $obs accessor - Update examples to use get_delay(est, "truncation") instead of get_delays(est)$truncation - Add unit test for merge_predictions_obs - Fix test for [[ accessor (deprecation already fired via $) Co-authored-by: sbfnk-bot <[email protected]>
Make it clear the helper is truncation-specific. Co-authored-by: sbfnk-bot <[email protected]>
Description
This PR closes #1143.
This PR closes #1236.
Return structure
observations: Raw input data (list of data.frames passed to the function)args: Stan data used for fittingfit: The stan fit objectS3 methods
get_delays(): Extracts estimated truncation distribution asdist_specget_predictions(): Computes truncation-adjusted estimates from samplesget_samples(): Returns raw MCMC samples for truncation distribution parameterssummary(): Returns parameter estimates with custom print method showing distribution contextplot(): Validation plot comparing observations to predictionsprint(): Shows summary (viaepinowfitsuperclass)Backward compatibility
$obs,$data,$last_obs,$cmf,$dist) with warnings[[accessor delegates to$for deprecated elementsOther changes
dist_types()todist_spec_distributions()in preparation for potential outsourcingepinowfitsuperclass for consistent print behaviourget_delays()intoepinowfitmethod used by all three estimation functionsreconstruct_delay()into smaller helper functionsextract_delays()andextract_parameters()to takeargsseparately (cleaner API)get_samples()output consistency: all methods now return bothvariable(category) andparameter(specific name) columnsInitial submission checklist
devtools::test()anddevtools::check()).devtools::document()).lintr::lint_package()).After the initial Pull Request