Changelog
Source:NEWS.md
menstrualcycleR 0.1.3
Fixed a bug in
pacts_scaling()where the user’s original date column was leftNAon fabricated calendar rows. To compute cycle lengths,pacts_scaling()internally densifies each participant’s calendar so that every missing day between their first and last observation becomes a row. Those fabricated rows received the package’s internal canonicaldate, but the column you passed in (e.g.daterated) was leftNAon them. When a cycle’s ovulation had to be imputed (no biomarker-confirmed ovulation), the imputed-ovulation day — along with itscyclic_time*/scaled_cycleday*values — could land on exactly such a fabricated row. A downstream analysis that joined the PACTS output back to other data by the original date column name would then silently drop those rows, quietly losing imputed-ovulation and scaled cycle-time observations.pacts_scaling()now returns a fully populated original date column: on fabricated rows it is filled from the internal calendar date, and observed dates are never overwritten. Character- and factor-typed date columns (a supported input) are coerced toDatethe same way the rest of the pipeline already coerces them;DateandPOSIXctdate columns keep their type. A regression test asserts that no row carries a realdateor a scaled/cycle value while the original date column isNA, acrossDate, character, factor, andPOSIXctdate inputs.Fixed the same class of bug for the user’s original ID column. The internal densify keeps the package’s canonical
idpopulated on fabricated calendar rows (it is the grouping key), but an original id column passed under a different name (e.g.record_id,subject) was leftNAon those rows — so a downstream join on id + date could still drop imputed-ovulation / scaled rows even after the date fix.pacts_scaling()now also refills the original id column from the canonicalidon fabricated rows (NA-fill only; observed ids are never changed and the column’s type is preserved). This was latent in typical use because the package’s own examples name the id columnid; it surfaces for datasets that use any other id column name. A regression test covers character and integer id columns under a non-idname.Fixed a bug in
pacts_scaling()where the last participant in a dataset could receiveNAfor the scaled cycle-time variables across an entire phase (most visibly the luteal phase, i.e.scaled_cycledayafterovtoday == 1). The internal phase-length loops (lutmax,folmax,folmax_imputeinhelper.R) detected the end of a phase by looking one row ahead and stopped atnrow(data) - 1, so the final row of the dataset was never treated as the end of a run. The result was position-dependent: reordering participants so that another came last moved the problem to that participant. The loops now treat the final dataset row as a valid run-end, and a regression test asserts that a participant’s scaled output is identical regardless of their position in the dataset. Thanks to Elisabeth Conrad (Freie Universität Berlin) for the clear bug report and reproduction. ([reported via PACTS user correspondence, June 2026])Packaging hygiene: declared
purrrinImports(used inhelper.Rbut previously undeclared), and addedtidyverseandmarginaleffectstoSuggestsso the overview vignette builds in a clean environment. Continuous integration (GitHub ActionsR-CMD-check) now runs the fullR CMD check— including the vignette — on every push and pull request.pacts_scaling()andcycle_plot_individual()no longer requiredplyr/tidyverseto be attached. Several internal calls to dplyr verbs (ungroup(),filter(),case_when(),first()) and torlang::sym()were not namespace-qualified, so a barelibrary(menstrualcycleR)producedError: could not find function "ungroup". All such calls are now qualified (dplyr::/rlang::), and every exported function works with the package loaded on its own.
menstrualcycleR 0.1.0
First release of menstrualcycleR, the companion R package to:
Nagpal, A., Schmalenberger, K. M., Barone, J. C., Mulligan, E., Stumper, A., Knol, L., Failenschmid, J., Kiesner, J., Peters, J. R., & Eisenlohr-Moul, T. A. (2025). Studying the Menstrual Cycle as a Continuous Variable: Implementing Phase-Aligned Cycle Time Scaling (PACTS) with the menstrualcycleR package. Psychoneuroendocrinology, 107584. https://www.sciencedirect.com/science/article/pii/S0306453025003075
Core functionality
-
pacts_scaling()computes continuous, phase-aligned cycle-time variables — the recommendedcyclic_time*measures (which map -1 and +1 to the same hormonal point) plus thescaled_cycleday*measures — centered on menses onset or ovulation, with optional ovulation imputation. -
cycle_plot()andcycle_plot_individual()visualize outcomes across the standardized cycle at the group and individual level, with rolling-average smoothing. -
cycledata_check()andsummary_ovulation()summarize data availability and confirmed-versus-imputed ovulation. -
launch_app()opens an interactive Shiny app for cycle scaling, data checks, visualization, and C-PASS (PMDD/MRMD/PME) diagnosis. -
cycledataprovides an example daily-diary dataset. - Vignette Getting Started with menstrualcycleR and Phase-Aligned Cycle Time Scaling (PACTS) walks through the full workflow, including GAMM modeling with
mgcvcyclic cubic regression splines.