Skip to content

Fix/block occ - #387

Merged
mnneely merged 8 commits into
mainfrom
fix/block_occ
Sep 3, 2026
Merged

mnneely merged 8 commits into
mainfrom
fix/block_occ

Conversation

@mnneely

@mnneely mnneely commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI lite review requested due to automatic review settings September 3, 2026 16:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

R/PM_final.R fallback upgrade paths overwrite PM_final_data classes and drop engine tags (e.g., NPAG), which breaks downstream plot/summary dispatch.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates the Pmetrics R API and data schema to replace the legacy block “observation block” concept with occasion, adding automatic upgrade support for older saved objects/data while keeping block available as a deprecated argument/column for backwards compatibility. It also removes the Rust mimalloc global allocator and makes small build/packaging adjustments.

Changes:

  • Introduce PM_upgrade() and apply it across constructors/plotters to transparently convert legacy block columns to occasion.
  • Update public entry points (make_AUC(), make_NCA(), plot methods, PM_pta$new) to accept occasion and deprecate block, plus add test coverage for deprecation behavior.
  • Remove the Rust mimalloc allocator dependency and tweak Makevars cleanup behavior.
File summaries
File Description
tests/testthat/test-occasion-deprecation.R New tests covering block → occasion deprecation behavior and upgrade semantics.
tests/testthat/test-makeAUC.R Update expectations from block to occasion in AUC outputs.
src/rust/src/lib.rs Remove mimalloc global allocator wiring.
src/rust/Cargo.toml Drop the mimalloc dependency.
Cargo.lock Remove mimalloc/libmimalloc-sys from the lockfile.
src/Makevars.in Adjust cleanup so build artifacts are removed outside the NOT_CRAN conditional.
src/Makevars Same cleanup adjustment as Makevars.in.
R/PMutilities.R Replace block-building helper with makePMdataOccasion(); update getCov() to exclude occasion.
R/Pmetrics-package.R Update imports (.env, DT::datatable, magrittr::not) for new usages.
R/PM_upgrade.R Add PM_upgrade() to upgrade legacy objects/frames from block to occasion.
R/PM_sim.R Switch to imported not() helper when filtering remaining data.
R/PM_pta.R Add occasion parameter; deprecate block; ensure legacy objects are upgraded before filtering.
R/PM_post.R Rename internal block field to occasion; upgrade legacy data; deprecate block plot arg.
R/PM_pop.R Rename internal block field to occasion; upgrade legacy data; deprecate block plot arg.
R/PM_op.R Rename internal block field to occasion; upgrade legacy data; deprecate block plot arg.
R/PM_final.R Upgrade legacy stored final data when reusing objects (but currently strips engine class tags in fallback paths).
R/PM_data.R Make occasion derived metadata; reserve occasion header; ensure writers strip it before engine output.
R/PM_cycle.R Upgrade legacy stored cycle data when reusing objects.
R/PM_cov.R Convert output block column to occasion and upgrade legacy stored cov data when reusing objects.
R/make_NCA.R Add occasion; deprecate block; upgrade legacy input components before filtering.
R/make_AUC.R Add occasion; deprecate block; upgrade legacy data before grouping/filtering.
R/globalVariables.R Register occasion for NSE/CRAN checks.
pkgdown/assets/Data/ObjectsR6.csv Update documented fields from block to occasion.
pkgdown/assets/Data/ObjectsLegacy.csv Update legacy object docs from block to occasion.
NAMESPACE Export PM_upgrade; add imports for DT::datatable, magrittr::not, and rlang::.env.
man/PMmatrixRelTime.Rd Documentation updates describing occasion-based splitting semantics.
man/PM_upgrade.Rd New generated Rd for PM_upgrade().
man/PM_pta.Rd Document new occasion arg and deprecated block.
man/PM_post.Rd Update field docs from block to occasion.
man/PM_pop.Rd Update field docs from block to occasion.
man/PM_op.Rd Update field docs from block to occasion.
man/PM_data.Rd Add link to online “Pmetrics in R book” format docs.
man/plot.PM_post.Rd Document new occasion arg and deprecated block.
man/plot.PM_pop.Rd Document new occasion arg and deprecated block.
man/plot.PM_op.Rd Document new occasion arg and deprecated block.
man/plot.PM_data.Rd Document new occasion arg and deprecated block.
man/make_NCA.Rd Document new occasion arg and deprecated block.
man/make_AUC.Rd Document new occasion arg and deprecated block.
man-roxygen/occasion.R New roxygen template text for occasion parameter docs.
man-roxygen/block.R Remove old roxygen template text for block.
inst/template/Cargo.toml Add Rust template Cargo manifest.
inst/report/templates/ggplot.Rmd Update report template to count distinct rows using occasion instead of block.
.Rbuildignore Ignore codecov.yml and Quarto vignette working directory.
Review details

Files not reviewed (4)

  • man/PM_data.Rd: Generated file
  • man/PM_op.Rd: Generated file
  • man/PM_pop.Rd: Generated file
  • man/PM_post.Rd: Generated file

Suppressed comments (2)

R/PM_final.R:252

  • This fallback path resets the upgraded object’s class to c("PM_final_data", "list"), which drops the engine tag (e.g., "NPAG" / "IT2B") needed by plot.PM_final()/summary.PM_final() to choose the correct behavior. PM_upgrade() already preserves attributes/classes on lists, so returning it directly keeps dispatch correct.
        upgraded_data <- PM_upgrade(data$data)
        class(upgraded_data) <- c("PM_final_data", "list")
        return(upgraded_data)

R/PM_final.R:266

  • This fallback path resets the upgraded object’s class to c("PM_final_data", "list"), which drops the engine tag (e.g., "NPAG" / "IT2B") needed by plot.PM_final()/summary.PM_final() to choose the correct behavior. PM_upgrade() already preserves attributes/classes on lists, so returning it directly keeps dispatch correct.
        upgraded_data <- PM_upgrade(data$data)
        class(upgraded_data) <- c("PM_final_data", "list")
        return(upgraded_data)
  • Files reviewed: 38/47 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread R/PM_final.R
Comment on lines +236 to +238
upgraded_data <- PM_upgrade(data$data)
class(upgraded_data) <- c("PM_final_data", "list")
return(upgraded_data)
Copilot AI review requested due to automatic review settings September 3, 2026 16:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Several new lifecycle::deprecate_warn() calls use a deprecation version (“3.3.0”) that is ahead of the current package version (3.2.6), which can cause lifecycle to error rather than warn.

Review details

Files not reviewed (3)

  • man/PM_data.Rd: Generated file
  • man/PM_op.Rd: Generated file
  • man/PM_pop.Rd: Generated file

Suppressed comments (8)

Previously missed (8) — in code that hasn't changed since the last review.

R/PM_data.R:1718

  • lifecycle::deprecate_warn() uses version "3.3.0", but the package DESCRIPTION version is 3.2.6; lifecycle expects the deprecation version to be <= the current package version and can error if it’s in the future.
    R/PM_op.R:383
  • lifecycle::deprecate_warn() uses version "3.3.0", but the package DESCRIPTION version is 3.2.6; lifecycle expects the deprecation version to be <= the current package version and can error if it’s in the future.
    R/PM_pop.R:259
  • lifecycle::deprecate_warn() uses version "3.3.0", but the package DESCRIPTION version is 3.2.6; lifecycle expects the deprecation version to be <= the current package version and can error if it’s in the future.
    R/PM_post.R:262
  • lifecycle::deprecate_warn() uses version "3.3.0", but the package DESCRIPTION version is 3.2.6; lifecycle expects the deprecation version to be <= the current package version and can error if it’s in the future.
    R/PM_pta.R:174
  • lifecycle::deprecate_warn() uses version "3.3.0", but the package DESCRIPTION version is 3.2.6; lifecycle expects the deprecation version to be <= the current package version and can error if it’s in the future.
    R/PM_upgrade.R:104
  • lifecycle::deprecate_warn() uses version "3.3.0", but the package DESCRIPTION version is 3.2.6; lifecycle expects the deprecation version to be <= the current package version and can error if it’s in the future.
    R/make_AUC.R:71
  • lifecycle::deprecate_warn() uses version "3.3.0", but the package DESCRIPTION version is 3.2.6; lifecycle expects the deprecation version to be <= the current package version and can error if it’s in the future.
    R/make_NCA.R:87
  • lifecycle::deprecate_warn() uses version "3.3.0", but the package DESCRIPTION version is 3.2.6; lifecycle expects the deprecation version to be <= the current package version and can error if it’s in the future.
  • Files reviewed: 40/48 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.73139% with 41 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.12%. Comparing base (5613287) to head (4020f68).

Files with missing lines Patch % Lines
R/PM_upgrade.R 70.00% 21 Missing ⚠️
R/PM_data.R 87.75% 6 Missing ⚠️
R/make_NCA.R 78.26% 5 Missing ⚠️
R/PM_op.R 91.89% 3 Missing ⚠️
R/PM_pta.R 91.30% 2 Missing ⚠️
R/PM_pop.R 96.15% 1 Missing ⚠️
R/PM_post.R 96.15% 1 Missing ⚠️
R/PM_sim.R 0.00% 1 Missing ⚠️
R/make_AUC.R 93.75% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #387      +/-   ##
==========================================
+ Coverage   62.73%   63.12%   +0.39%     
==========================================
  Files          51       52       +1     
  Lines       22410    22545     +135     
==========================================
+ Hits        14059    14232     +173     
+ Misses       8351     8313      -38     
Files with missing lines Coverage Δ
R/PM_cov.R 74.24% <100.00%> (-0.12%) ⬇️
R/PM_cycle.R 78.36% <100.00%> (-0.46%) ⬇️
R/PM_final.R 77.48% <100.00%> (-0.55%) ⬇️
R/PMutilities.R 25.00% <100.00%> (+0.61%) ⬆️
R/PM_pop.R 75.63% <96.15%> (ø)
R/PM_post.R 75.81% <96.15%> (+0.02%) ⬆️
R/PM_sim.R 67.14% <0.00%> (-0.13%) ⬇️
R/make_AUC.R 94.64% <93.75%> (+0.52%) ⬆️
R/PM_pta.R 73.71% <91.30%> (+0.25%) ⬆️
R/PM_op.R 76.80% <91.89%> (-1.37%) ⬇️
... and 3 more

... and 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mnneely
mnneely marked this pull request as ready for review September 3, 2026 17:04
Copilot AI review requested due to automatic review settings September 3, 2026 17:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new occasion metadata plumbing has a confirmed ordering-sensitivity bug and the new reserved-header check can falsely error on valid case-variant occasion columns.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Files not reviewed (2)

  • man/PM_data.Rd: Generated file
  • man/PM_op.Rd: Generated file
  • Files reviewed: 42/49 changed files
  • Comments generated: 3
  • Review effort level: Lite

Comment thread R/PM_data.R
Comment on lines +881 to +896
occasion_name <- names(data2)[tolower(names(data2)) == "occasion"]
if (length(occasion_name) > 0 && !source %in% c("PM_data", "list")) {
is_occasion_metadata <- identical(occasion_name, "occasion") &&
all(c("id", "evid") %in% names(data2)) &&
isTRUE(all.equal(
data2$occasion,
makePMdataOccasion(data2)$occasion,
check.attributes = FALSE
))
if (!is_occasion_metadata) {
cli::cli_abort(c(
"x" = "{.field occasion} is a reserved Pmetrics data header and cannot be used as a covariate name.",
"i" = "Rename that covariate before calling {.fn PMcheck}."
))
}
}
Comment thread R/PMutilities.R
Comment on lines +323 to +327
# Assign observation occasions, delimited by EVID = 4 and stored in `occasion`.
mdata <- mdata |>
dplyr::group_by(id) |>
dplyr::mutate(occasion = 1L + cumsum(dplyr::coalesce(evid == 4, FALSE))) |>
dplyr::ungroup()
Comment thread src/rust/src/lib.rs
Comment on lines 2 to 6
mod logs;
mod settings;
mod simulation;

use mimalloc::MiMalloc;

/// Use mimalloc as the global allocator for improved allocation performance
/// across Windows, macOS, and Linux.
#[global_allocator]
static GLOBAL: MiMalloc = MiMalloc;

use anyhow::Result;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mnneely, was this intentional?

Copilot AI review requested due to automatic review settings September 3, 2026 17:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There are a couple of small but user-visible correctness issues (occasion type stability and lifecycle deprecation version reporting) that should be fixed before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Files not reviewed (2)

  • man/PM_data.Rd: Generated file
  • man/PM_op.Rd: Generated file

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

R/PMutilities.R:327

  • cumsum() returns a double, so occasion will be stored as a double even though it is conceptually an integer index. This can cause type mismatches (e.g., strict comparisons or joins) and is easy to avoid by casting to integer after computing the cumulative sum.
  • Files reviewed: 42/49 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread R/PM_upgrade.R
Copilot AI review requested due to automatic review settings September 3, 2026 17:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

PMcheck() can accept occasion metadata without enforcing it as trailing metadata, which can break covariate indexing assumptions used by downstream validation/reporting.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Files not reviewed (2)

  • man/PM_data.Rd: Generated file
  • man/PM_op.Rd: Generated file
  • Files reviewed: 42/49 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread R/PM_data.R
Comment on lines +881 to +896
occasion_name <- names(data2)[tolower(names(data2)) == "occasion"]
if (length(occasion_name) > 0 && !source %in% c("PM_data", "list")) {
is_occasion_metadata <- identical(occasion_name, "occasion") &&
all(c("id", "evid") %in% names(data2)) &&
isTRUE(all.equal(
data2$occasion,
makePMdataOccasion(data2)$occasion,
check.attributes = FALSE
))
if (!is_occasion_metadata) {
cli::cli_abort(c(
"x" = "{.field occasion} is a reserved Pmetrics data header and cannot be used as a covariate name.",
"i" = "Rename that covariate before calling {.fn PMcheck}."
))
}
}
Copilot AI review requested due to automatic review settings September 3, 2026 18:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

PMcheck() accepts valid derived occasion metadata but does not relocate it, which can cause occasion to be misinterpreted as a covariate (or hide a real covariate) in downstream covariate range logic.

Review details

Suppressed comments (1)

R/PM_data.R:885

  • When a valid derived occasion column is present in a PMmatrix (i.e., is_occasion_metadata is TRUE), PMcheck() currently leaves it in-place. This can break downstream covariate handling (e.g., getCov()/errcheck() assume covariates are a contiguous block after the fixed columns), causing occasion to be treated as a covariate or a real covariate to be skipped unless occasion happens to be the last column. Consider relocating occasion to the end once it is validated as metadata.
  occasion_name <- names(data2)[tolower(names(data2)) == "occasion"]
  if (length(occasion_name) > 0 && !source %in% c("PM_data", "list")) {
    is_occasion_metadata <- identical(occasion_name, "occasion") &&
      all(c("id", "evid") %in% names(data2)) &&
      isTRUE(all.equal(
  • Files reviewed: 44/52 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@mnneely
mnneely merged commit f1e720d into main Sep 3, 2026
10 of 11 checks passed
@mhovd
mhovd deleted the fix/block_occ branch September 4, 2026 07:42
@mhovd
mhovd restored the fix/block_occ branch September 4, 2026 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants