NEWS


rmorie 2026-10-20 (2026-10-20)

rmorie 2026-10-19 (2026-10-19)

rmorie 2026-10-16 (2026-10-16)

rmorie 2026-10-09 (2026-10-09)

rmorie 2026-10-08 (2026-10-08)

rmorie 2026-10-07 (2026-10-07)

rmorie 2026-10-03 (2026-10-03)

rmorie 2026-10-01 (2026-10-01)

Command line: every Python verb has an R twin

Pollution -> health

Compute emissions with provenance

Command line

Your own model

CRAN follow-ups

Continuous integration

rmorie 2026-09-30 (2026-09-30)

See what you can ask

Bayesian optimisation

SIU manifest and README

Release hygiene

Hosted LLM tier

Command line inside the package

Policing, public safety and search

Spatial statistics

Political science

Optimisation and operations research

Statistics from the bookshelf

Causal inference against the reference packages

Other estimators verified against R

Clustering, networks and symbolic computation

Environmental, earth and life sciences

Criminology research program

Tests behind every export

Windows

Security

Parameters that were accepted and not read

An AST scan over the package found defaulted arguments never referenced in their bodies. Those documented as no-ops are unchanged; the rest now act: cramers_v() carries a noncentral chi-square interval at confidence, random_effects_meta() implements method = "PM" and "REML", link_test() fits model_type = "logistic", morie_rdd_plot_data() returns the local fits (cutoff, p_local, bandwidth, kernel), morie_rdd_sharp() bootstraps by cluster, morie_rdd_bandwidth_rot() reports both sides of cutoff, morie_weights_greg() iterates to max_iter, morie_matching_att_matched() weights by the named column, morie_matching_abadie_imbens_se() divides the reuse count by n_matches, morie_brunner_munzel(), morie_iv_anderson_rubin(), Landmark() and Aftfit() use alpha, the ingest helpers send user_agent, morie_bayes_lm() honours stop_on_convergence, and morie_spatial_voting_aldrich_mckelvey() refuses n_dims != 1 instead of ignoring it.

Two-proportion test

mrm_twoprop_test() with no events (or nothing but events) in both arms returns chi-square 0 with p = 1 and warns, instead of NaN from chisq.test(). This is morie's own convention (the limit of two identical arms), the same one the Python arm adopted in 1.3.2, so the two arms agree again on degenerate tables.

Missing values

morie_fairness_gini() is NA with a warning and an "undefined" interpretation when a value is missing or non-finite (it returned 0, "relatively evenly spread"). morie_tox_left_censor_impute() no longer counts NA as below the detection limit: it stays NA, is left out of fraction_censored, and is reported as n_missing. Same change in the Python arm.

Spatial voting

Every basicspace call (morie_spatial_voting_aldrich_mckelvey(), morie_spatial_voting_blackbox(), morie_spatial_voting_bayesian_am()) is gated on a double matrix with at least two rows and two columns: basicspace 0.25's Fortran writes past its arrays on a single-row or single-column input and the process dies later (valgrind). Thin inputs take the native path. morie_spatial_voting_aldrich_mckelvey() reaches basicspace as documented: it passed missing = NA, which basicspace rejects, so every call had taken the fallback. Its numbers change: the stimulus positions are now basicspace's, standardised to mean 0 and sd 1. On data with structure to recover the two engines agree closely (stimuli correlate about 0.97, intercepts 1.00) but not exactly; on structureless noise they do not agree at all (0.04), as nothing constrains either. The respondent intercepts and slopes are the per-respondent regression of the placements on those positions on either engine, so they are defined for every respondent; basicspace reports them only against a self-placement, which this function does not take, and a 1-7 scale had given all-NA respondent parameters. Non-finite stimuli from basicspace fall back to the native solver.

Clustering

predict.morie_cluster() computes the n x k distances to the centroids directly. It built the full (n + k)^2 distance matrix and kept n x k of it: 6 s and 2.8 GB at n = 10,000 for a 4 ms job, and out of memory at n = 20,000. morie_cluster() gains iter_max for the k-means iteration cap. One example and one test used R 4.4 idioms (%||%, psmirnov(alternative =)) on a package that declares R >= 4.3.0.

rmorie 2026-09-21 (2026-09-21)

Canadian legal data: A2AJ and CanLII clients

Seven morie_ingest_a2aj_*() functions cover the A2AJ Canadian Legal Data corpus (about 226,000 court and tribunal decisions and 27,000 statutes and regulations, maintained by Access to Algorithmic Justice at Osgoode Hall and Toronto Metropolitan University): _coverage() lists what the corpus holds, _search() and _fetch() wrap the REST API, _download() and _load() bring one court's Parquet file from Hugging Face into a data.frame, _citation_edges() turns the cited-cases field into an edge list, and _gaps() tabulates the courts the corpus does not carry. Every record carries its upstream_license.

Eight morie_ingest_canlii_*() functions wrap CanLII's REST API for those gaps (the Human Rights Tribunal of Ontario, the BC Human Rights Tribunal, the Ontario Superior Court, Alberta, Quebec and the remaining provinces): databases, per-court decision lists with date filters, one decision's metadata, the citator (cited cases, citing cases, cited legislation), and the legislation browse; _case_id() derives CanLII's identifiers from a neutral citation. A free key is read from CANLII_API_KEY.

The native Parquet reader now decodes three-level LIST columns (one vector per row, NULL for a null list), which is how the A2AJ citation network fields are stored; other nesting is still refused rather than silently mis-counted. The mrm-dataset-fetchers vignette gains a section on both sources.

Fixes

rmorie 2026-09-19 (2026-09-19)

Design and measurement for small or under-enumerated subpopulations

Fifteen functions for studies whose target group is a small share of the frame, is reached by a design that is not simple random sampling, or is imperfectly identified by the frame itself. The three problems compound, and the package previously covered only the estimators, not the planning.

Sample size and design: morie_sample_size_proportion() composes the finite population correction, a design effect and a non-response inflation in that order; morie_sample_size_domain() answers the question the estimators could not, namely how large the whole sample must be for the subgroup to reach a stated precision, dividing by both the subgroup share of the frame and the rate at which the frame identifies it. morie_deff_cluster() and morie_neff_cluster() give the clustering component of the design effect, which multiplies with the weight component from morie_design_effect(). morie_oversample_factor() returns the selection multiplier for a target composition together with the weight-induced design effect it creates, so the two are planned together rather than in sequence. morie_screen_design() costs a two-phase screen for a rare group. morie_alloc_optimal() allocates across strata with unequal per-unit costs, reducing to Neyman() when costs are equal.

Weighting: morie_rake() performs iterative proportional fitting to known margins, reporting convergence rather than assuming it.

Identification error: morie_misclass_correct() and morie_misclass_count() implement the Rogan-Gladen correction, which recovers a prevalence from an observed one when the classifier has known sensitivity and specificity. Where group membership is recorded administratively rather than self-reported, sensitivity below one biases every rate computed on the recorded counts.

Measurement equivalence: morie_dif_sample_size() sizes a differential item functioning comparison, whose power is governed by the smaller group; morie_dif_delta_mh() puts a Mantel-Haenszel odds ratio on the ETS delta scale with its A/B/C classification; morie_invariance_compare() runs the nested configural/metric/scalar sequence on chi-square, CFI and RMSEA; morie_irt_theta_se() and morie_irt_marginal_reliability() report score precision, which is worth reporting by group for the same reason DIF is.

New vignette subpopulation-design, including the governance framework the arithmetic sits inside.

rmorie 2026-09-18 (2026-09-18)

Twenty-one modules from morie's R arm, three-way verified

Sixteen modules that morie added in September and rmorie lacked now ship here too, each checked against the Python arm and morie's R arm on identical inputs to twelve digits with falsifiable anchors (ledger/wave3/run3.sh): the bound families Bndcvr, Bndlgt, Bndnmt, Bndsdo, Bnsipv; the clustered-design family Ccdsgn, Ccmem, Ccngg; Cluseq, Cnsint, Crrcim, Cumcif, DepthP, DepthS, Difpst and Rdmcbw. Five more come across without a Python twin: morie_fairness_spatial_gan() and its family, the BPE tokenizer (morie_tokenizer_new() and friends), the OTIS MAPQ study module, the plot() method for morie_rich_result objects, and Qrf (quantile forest pinball loss). torch and reticulate join Suggests as the optional backends the fairness GAN and tokenizer can use.

Functions that seed the RNG now leave the caller's stream alone

Two hundred and thirty-six functions called set.seed() internally and left the session's random stream replaced, so a user who had seeded their session for reproducibility got identical downstream draws whatever seed they had chosen. Every one of those sites now seeds for the rest of that call only and restores the caller's stream (or its absence) on exit; the seeded results themselves are unchanged. morie_det_rng() still seeds the session, which is its documented purpose, but the twenty-six functions that call it on their deterministic_seed path now restore the caller's stream as well.

The compiled mean no longer overflows where base R does not

morie::core::mean() in src/morie_core.h, reached by morie_mean_cpp() and by everything built on it (variance, standard deviation, moments, bootstrap means), summed naively: rep(1e308, 3) gave Inf and rep(1e120, 3) was off by 1.4e104, so the variance of three identical values came back as 3e208. It now uses base R's algorithm (extended precision sum plus one corrective pass) with a running mean as the fallback when the sum overflows although every input is finite. Results on ordinary data are bit-identical to mean(). morie_mean_cpp() and morie_var_cpp() gain a shared argument: TRUE (the default) uses the rmoriebricklayer kernel and FALSE the identical kernel rmorie vendors; morie_mean() and morie_var() pick the vendored one whenever the installed rmoriebricklayer predates 0.5.1, so the answer never depends on which bricklayer build resolved.

Non-finite propensity scores no longer abort optimal matching

The exact 1-D optimal matching kernel sorted its scores with <, which is not a strict weak ordering when a score is NaN or Inf; under the libstdc++ assertions that Fedora and Debian compile R packages with, that aborted the whole R session. The kernel now refuses non-finite scores with an error naming the element.

Undefined effect sizes and bootstraps warn

morie_cohens_d() warns when the denominator standard deviation is zero or missing instead of returning Inf or NaN silently, and morie_bootstrap_ci() warns when x has fewer than two observations.

Fixed

Installation is about twice as fast

ByteCompile: no. Byte-compiling the package at install time took half of the install (about four minutes on a laptop); R compiles functions on first use anyway, so nothing is lost at run time.

Eighty-eight documented functions are now exported

Eighty-eight functions carried full roxygen documentation, references and examples but no @export, so their examples reached them through rmorie:::. Most are the genomic-prediction and kernel-method family (morie_gblup(), morie_kernel_matrix(), morie_msm_*(), morie_fda_*()), the AlphaFold loss functions (Alfviol() and its siblings) and morie_laplc(). All are exported now and their examples call them directly.

pkgdown

DESCRIPTION lists the pkgdown site URL, which pkgdown::check_pkgdown() requires.

mrm_otis_stock_flow, and the Lakner stock/flow measures

The MRM OTIS family gained the Lakner (1976) decomposition: average daily population as a stock (sum(x_i)/t, days per day), average length of stay as a flow (sum(x_i)/N, days per person), and the identity that ties them (adp = N_a * alos / t). Flow and stock rates can carry opposite signs over the same period, so reporting one as if it were the other reverses the finding -- it did for an OTIS headline before this landed.

No test in the package had ever skipped

tests/testthat/setup.R decided whether it was running under R CMD check by reading R_TESTS. R sources that file at startup and then unsets it, so the variable is always empty by the time the setup file runs: every skip_on_cran() in the package was inert, on CRAN included. The discriminator is now _R_CHECK_PACKAGE_NAME_, which survives. With the gates actually firing, the tests stage dropped from 956s to 192s and the whole check from over an hour to about 39 minutes -- which is what brought it back inside r-universe's sixty-minute budget.

The SIU index is no longer swept under R CMD check

.siu_resolve_drid() and its fetch path reached the live index on every check run. They now return NA_integer_ unless live fetches are explicitly allowed, so a check no longer depends on a third party being up.

Kernel symmetry is imposed, not assumed

.gh_pairwise_sq() built its Gram matrix from a BLAS call whose result is only symmetric up to rounding, and the Cholesky downstream rejected it on some platforms. The matrix is now symmetrized explicitly. morie_ghgpm() also checks finiteness first and preserves the real chol() error instead of replacing it.

rmoriebricklayer floor

rmoriebricklayer (>= 0.4.8) is required for the native decimal conversion; older copies are skipped rather than failed.

rmorie 2026-09-09 (2026-09-09)

morie_digest2int matches digest on arm

digest::digest2int() hashes a plain char, whose signedness is the platform's: signed on x86, unsigned on arm. The native kernel forced signed char, so it agreed with digest on x86 and diverged on arm for any byte above 0x7f -- the r-universe arm64 builds failed on "é", expecting -1366949649 and getting 26298542. The cast now follows the platform, as digest does.

rmorie 2026-09-08 (2026-09-08)

The Rd manual builds again

R CMD Rd2pdf failed on 1.2.1's sources, which is what the CRAN check reported as "checking PDF version of manual without index ... ERROR". Three causes, none of them visible without running the build:

Also removed: a data() call that read as a load into the global environment, a stray top-level 5.rds, and literal angle-bracket placeholders that reached the HTML manual as unrecognised tags.

Each fixture ships once

inst/ went from 2.18 MB to 0.25 MB, and the tarball from 11.66 MB to 9.73 MB: 54 fixtures byte-identical to rmoriedata's are resolved from there at runtime, the generated dataset catalogue is built on demand, and describe_corpus.Rds moved to rmoriedata with the rest of the data.

CRAN compliance: \dontrun becomes \donttest

CRAN's rule is that \dontrun marks an example the user cannot run -- missing software, an API key -- and that everything else belongs in \donttest, because \dontrun prints a "# Not run:" warning that misleads the reader. 157 example blocks were wrapped in \dontrun purely because they reach the network, which is not a reason CRAN accepts: they are runnable, they are already guarded with try(), and they degrade cleanly offline. They are now \donttest.

\dontrun is kept in the handful of places it is correct: the Vertex token/Gemini calls, the StatCan and NIBRS ingests that need an API key, and install_extras(), which installs packages.

CI keeps its speed through _R_CHECK_DONTTEST_EXAMPLES_: false rather than through misleading markup -- --as-cran executes \donttest, and on a GitHub runner the network examples crawl against throttled services until the job times out. CRAN's own machines decide for themselves; the full example sweep runs on L14.

Native specializations: the dependency-light release

This release merges the feat/native-specializations line (650 commits). Every estimator that previously delegated to a heavy runtime dependency now has a native implementation, cross-validated against the package it replaces and benchmarked: double-ML runs 40-61x faster than DoubleML, the R-learner causal forest 2.9x faster than grf, optimal matching beats optmatch's own optimum, and design-based GLM matches svyglm to 1e-6. The full matrix is green on Windows, macOS, Ubuntu (release, devel, oldrel-1) and a true Debian bookworm container.

Wave 3: every ledger module implemented three-way

Native JSON codec, complete (2026-09-02)

Native hash family (digest's surface, 2026-09-02)

Documentation reconciliation (2026-09-01)

Documentation marathon

Fixed (found by executing paths that had never run)

rmorie 2026-07-22 (2026-07-22)

Patch release: 07-22 hardening + CRAN prep (lockstep with morie 1.1.6)

rmorie 2026-07-15 (2026-07-15)

rmorie 2026-05-25 (2026-05-25)

CI: drop fwildclusterboot (pak recursive Remotes unreliable) (3MMM.40c)

CI: pak resolver -- transitive Remote for summclust (3MMM.40b)

R CMD check ERROR fixes (3MMM.39)

CI: setup-r-dependencies pak resolver unblocked (3MMM.40)

rmorie 2026-05-24 (2026-05-24)

Correctness recovery: math typesetting restored

Phase 3LLL reverses the destructive \eqn{LATEX} -> \code{LATEX} swap shipped in commit f399ec41a (Phase 3KKK1+2). That swap eliminated the "Lost-braces" warning but at the cost of stripping LaTeX math typesetting from the PDF/HTML manual and turning every greek letter, \hat, \sum, \frac, etc. into an "unknown macro" warning at R CMD check.

The proper Rd-compliant fix is the two-argument form:

\eqn{LATEX}{ASCII fallback}      # inline
\deqn{LATEX}{ASCII fallback}     # display

Every affected line (104 R files) now uses this form, preserving PDF math while satisfying the Rd parser. Driven by fix_rd_math.py, a LaTeX->ASCII transformer covering the common Greek alphabet, operators (\sum, \int, \hat, \bar, \frac, \sqrt), and relation symbols.

Auto-install helper for optional dependencies

New morie_install_extras() lets users install the ~50 optional Suggests: packages in one call. CRAN policy forbids install.packages() at .onLoad() time, so morie ships an opt-in helper instead. Three modes:

morie_install_extras()                       # missing only (default)
morie_install_extras("all", ask = FALSE)     # everything, CI-safe
morie_install_extras(c("hawkes", "sf"))      # named subset

The helper also probes for the C system libraries libcurl, libsodium, and liboqs and prints platform-specific install hints when any are missing. System libraries must be installed BEFORE re-installing morie so the configure-time probes link the C/C++ backends against them.

Bulk open-data catalog explosion

Cross-portal morie_dataset_portal_catalog() grows from ~1,044 rows to 9,242 rows across 14 portals. Every Socrata / CKAN / ArcGIS Hub / Opendatasoft portal morie touches now has its full public catalog integrated offline.

Phase 3GGG -- 6-portal bulk harvest

Phase 3HHH -- full catalogs for the last two portals

Catalog totals

calgary_opendata      933    nyc_opendata          2861
chicago              1864    ontario_ckan            38
edmonton_opendata    2027    ottawa_opendata        287
montreal_opendata     401    statcan_ccjs            10
nyc_nypd                8    toronto_opendata       540
tps_arcgis_hub         71    tps_psdp                11
vancouver_opendata    190    vpd_geodash              1
                                                  -------
                                                     9242

Integrated fixture footprint: ~3.4 MB of catalog metadata; per-row unwound this is the metadata equivalent of every NYC dataset descriptor + every CKAN package summary + every Hub item -- offline queryable via morie_datasets_browse(keyword=...).


Cross-portal open-data infrastructure

Major sprint adding 14 open-data portals + a unified browse/load interface. The cross-portal morie_dataset_portal_catalog() now spans 9 cities + 1 federal source + ~800 dataset entries across 4 different API protocols.

Phase 3CCC -- NYC + TPS deep coverage

Phase 3DDD -- Canadian municipal + federal coverage

Phase 3EEE -- Montreal + expanded Toronto/Vancouver + dispatcher

Phase 3FFF -- dispatcher hardening + prairie cities

Catalog totals (across 14 portals)

chicago             8     ontario_ckan       38
nyc_nypd            8     vancouver_opendata 190
nyc_opendata       10     vpd_geodash         1
tps_arcgis_hub     71     statcan_ccjs       10
tps_psdp           11     montreal_opendata  23
                          toronto_opendata  208
                          calgary_opendata  157
                          edmonton_opendata 195
                          ottawa_opendata   106

Total ~ 1044 catalog rows.


rmorie 2026-05-23 (2026-05-23)

Formula corrections (affect Python AND R sibling identically):

R-side feature additions:

Other fixes carried from the 5-layer review on 2026-05-22 (all Python-parity-verified before applying):

Earlier from 2026-05-22 marathon (already in 0.9.5.6 in tree):

rmorie 2026-05-22 (2026-05-22)

R-side describe() parity closure. Patch release that closes one of the two parity gaps named in v0.9.5.4: the pedagogical narratives that the Python sibling exposes via morie.describe() are now available on the R side via morie_describe() and the string-only variant morie_describe_by_name().

R API additions:

Integrated data:

Build tooling:

Tests:

Remaining parity gap:

rmorie 2026-05-21 (2026-05-21)

Doob → MRM chi-square rename. Patch release with deprecation aliases; no breaking changes for existing user code.

Naming:

Python API (with deprecation aliases):

R side: no R API changes; the R chi-square family was already renamed in v0.9.5 (vignette chi-square-and-anova.Rmd).

Patch release over 0.9.5.2.

CRAN Policy: full cache-leak fix (supersedes 0.9.5 which was uploaded to win-builder with incomplete cache-isolation).

Documentation + CI hardening (added 2026-05-21 to the v0.9.5 release branch alongside the SIU + rename work):

lintr / goodpractice cleanups:

SIU harvester: polite by default, manifest-aware, retry-aware, and auditable against the original published reports.

New: a generic open-data access layer, and a much wider dataset catalog.

Fix: Toronto Police Service open-data ingestion correctness and reliability.

rmorie 2026-05-18 (2026-05-18)

Fix: CRAN source-package compliance for the vendored C++ core header.

rmorie 2026-05-17 (2026-05-17)

Fix: complete the Docker image build fix; atomic release pipeline.

Fix: the Docker container build for the v0.9.1 C/C++ core.

New: a shared C/C++ computational backend and a Hawkes-process engine.

rmorie 2026-05-16 (2026-05-16)

New: dataset availability auditing, more open-data sources, and in-place self-update.

New: the fairness & disparity-audit subsystem (morie.fairness).

A subsystem for auditing risk-assessment, recidivism, and predictive-policing systems for racial and other group disparities. morie does not deploy such systems — it measures whether an existing one encodes disparate treatment, so researchers and oversight bodies can hold those systems accountable.

The methods are implemented from published descriptions — IBM AIF360; the SciencesPo Predictive-policing-Chicago project; Barman & Barman (arXiv:2603.18987); and the COMPAS audit in pbiecek's XAI Stories.

Security patch.

rmorie 2026-05-15 (2026-05-15)

License change. morie is now licensed under the GNU Affero General Public License v3 or later (AGPL-3), on both the Python and R sides.

rmorie 2026-05-14 (2026-05-14)

Documentation-only patch on top of 0.7.1. Supersedes the in-queue 0.7.1 submission for the rOpenSci pre-submission inquiry / next CRAN bump.

rmorie 2026-05-11 (2026-05-11)

rmorie 1.1.4

Modules 14-17 (quasi-experimental front-ends, weighting, modern DiD, crim methods)

Major changes

Breaking changes

Bug fixes

Dependencies

rmorie 1.1.2

CLI analysis entry point + NYPD/CPD backends

Security hardening (parity with the morie ecosystem)

Non-breaking trust-boundary guards on the process-execution and deserialization sinks. Defaults are unchanged; these add a kill-switch and a single choke point (see the new internal R/aaa_exec_guard.R).

All system2() sinks continue to use argv lists (no shell-string interpolation); that invariant is now documented in the guard file.

rmorie 1.1.0

CI hardening (docs-site build) + version re-lock with morie

rmorie 1.0.5

Figures actually write now

rmorie 1.0.4

rmorie 1.0.3

rmorie 1.0.2

rmorie 1.0.1

rmorie 1.0.0

rmorie 0.9.9

rmorie 0.9.8

rmorie 0.9.6

Bugfix: cluster-robust SE with empty cluster levels

Citation cleanup: remove Zenodo references

Phase 1 hotfix: drop wrappers for CRAN-archived packages

Phase 1.n: FDR/nonparam extenders -- locfdr / fdrtool / quantreg / np / dirichletprocess / lcmm

Phase 1.m: spatial/multivariate extenders -- gstat / copula / kernlab / metafor / mvtnorm

Phase 1.l: RDD/IRT extenders -- rddensity / rdlocrand / rdpower / anchors / anominate

Phase 1.k: stats extenders -- DescTools / performance / ppcor / coin / randtests

A new file R/extenders_stats.R adds 17 wrapper-as-extender entry points under the canonical morie_<pkg>_* prefix that delegate to five CRAN statistics packages. Each function follows the requireNamespace-guarded hard-error pattern used by the other 1.g/1.h/1.i/1.j extenders and returns a thin two-slot list with $method (qualified upstream name) and $raw (upstream object):

DESCRIPTION: adds DescTools, ppcor, randtests to Suggests (alphabetised). coin and performance were already listed.

Tests: tests/testthat/test-extenders-stats.R covers one happy path per function, each gated by skip_if_not_installed().

Phase 1.g gap: TwoWayFEWeights + synthdid extender

Two new wrapper-as-extender entry points have been added to R/did.R to close the Phase 1.e gap. Both follow the requireNamespace-guarded hard-error pattern of the existing DiD wrappers and ship under the canonical morie_did_* namespace:

DESCRIPTION: adds TwoWayFEWeights to Suggests. synthdid was already listed in 0.9.5.12.

Tests: tests/testthat/test-did-extender.R covers both the happy path (skipped when the optional package is not installed) and the missing-package error path.

Phase 1.g sensitivity rewrite - extend EValue / tipr / sensemakr / konfound

The sensitivity subsystem (R/sensitivity.R, ~733 LOC) keeps its existing inline math as a fallback arm but cross-references the canonical CRAN packages (rbounds, tipr, sensemakr, specr, episensr) in the Rd files, and four new wrapper-as-extender entry points have been added so MRM / paper callers can reach the full surface of these packages from inside rmorie:

All four hard-error with a clear install.packages(...) message if the optional dependency is missing, matching the Phase 1.e / 1.f pattern.

rosenbaum_bounds, tipping_point_analysis, omitted_variable_bias, specification_curve, and probabilistic_bias_analysis are kept in-house (the rmorie result shapes are part of the public API and the inline math remains the reference fallback). manski_bounds, bias_adjusted_estimate, and sensitivity_summary are novel / aggregator code with no clean CRAN counterpart.

DESCRIPTION: adds tipr, sensemakr, konfound to Suggests.

Tests: tests/testthat/test-sensitivity.R extended with eight new test_that() blocks (one happy path + one missing-package error path per new extender, all gated by skip_if_not_installed).

R/causal.R rewrite + new causal extenders

The causal-inference subsystem (~876 LOC) has been thin-wrapped over the canonical CRAN causal-inference packages while preserving every inline math fallback for CRAN-only installs (dual-arm pattern).

Four new extender functions are introduced for CRAN dependencies that previously had no morie_* entry point:

The four extenders hard-error on missing packages (no inline fallback) since each upstream implementation is too large to re-implement compactly. New tests live in tests/testthat/test-causal-extenders.R and are guarded with skip_if_not_installed().

DESCRIPTION Suggests now lists AIPW, CausalImpact, causalweight, rbounds, sensitivitymv, and stdReg so the extenders and the delegation arms can find their upstream packages when available.

R/bootstrap_methods.R rewrite - delegate to boot / bootstrap / resample / rsample / simpleboot / coin / ipred / sandwich

The bootstrap / resampling subsystem (~867 LOC) has been re-routed through the canonical CRAN packages while preserving the rmorie API and the morie_bootstrap_result / morie_jackknife_result / morie_permutation_test_result / morie_cv_result S3 return shapes so that stat_commands, the print methods, and MRM analyses keep working unchanged.

Thin-wrapped (with requireNamespace-guarded delegation arm + inline fallback so the wrapper keeps working on minimal installs):

Kept as in-house implementations (no clean CRAN drop-in for the rmorie API):

Added four new extender entry points (thin pass-through to the canonical packages):

DESCRIPTION: adds boot, bootstrap, coin, ipred, resample, rsample, simpleboot to Suggests (sandwich was already present).

Function inventory is preserved: 11 prior exports kept (bootstrap, parametric_bootstrap, wild_bootstrap, block_bootstrap, jackknife, delete_d_jackknife, permutation_test, paired_permutation_test, subsampling, bootstrap_632, repeated_cv, leave_one_out_cv) plus 4 new (morie_boot_run, morie_boot_basic_ci, morie_rsample_bootstraps, morie_simpleboot_two). All 20 (15 prior + 5 new) tests/testthat/test-bootstrap_methods.R test_that blocks pass (73 expectations, 2 conditional skips when rsample or simpleboot is not installed).

R/effects.R rewrite - thin-wrap over emmeans / marginaleffects / broom / stdReg / rbounds / EValue (phase 1.j)

The treatment-effect / marginal-effects module has been thin-wrapped around its canonical CRAN extender packages and gained a new family of morie_effects_* wrappers over Vincent Arel-Bundock's marginaleffects API plus the emmeans and broom ecosystems.

Thin-wrapped (existing API preserved; requireNamespace-guarded delegation arm + inline fallback so the wrapper keeps working on CRAN-only installs):

New extender wrappers (each a thin pass-through; the underlying package's native object is returned verbatim so downstream code keeps working with the canonical API):

The effects and margins packages are added to Suggests for the cross-reference path -- users who want Fox's effect() / predictorEffects() or Leeper's Stata-style margins::margins() can call them directly on a model fitted via rmorie, without an intervening wrapper.

DESCRIPTION: adds broom, effects, emmeans, marginaleffects, margins, performance, rbounds, stdReg to Suggests.

Net: R/effects.R grows from 461 to ~640 LOC because the legacy treatment-effect functions now carry both a CRAN-delegation arm AND an inline fallback (CRAN policy does not allow Suggests to be hard required), plus 5 new extender wrappers + 1 shared helper. All 6 legacy exports preserved (estimate_ate, estimate_plr, estimate_pliv, estimate_ate_gcomputation, sensitivity_rosenbaum, e_value); 5 new exports added (morie_effects_emmeans, morie_effects_predictions, morie_effects_comparisons, morie_effects_slopes, morie_effects_tidy).

R/multiple_testing.R rewrite - delegate to poolr / qvalue / harmonicmeanp / gMCP / mutoss

The multiple-testing-correction subsystem (~916 LOC) has been rewritten to forward to the canonical CRAN / Bioconductor packages where one exists. Every wrapper preserves the rmorie API and the morie_multiple_testing_result / morie_rich_result S3 shape so that the stat_commands dispatcher, the print.morie_multiple_testing_result method, and MRM analyses keep working unchanged.

Thin-wrapped (with requireNamespace-guarded delegation arm + inline fallback so the wrapper keeps working on CRAN-only installs):

Kept as in-house implementations (no clean CRAN drop-in for the rmorie API):

DESCRIPTION: adds poolr, qvalue, gMCP, harmonicmeanp, multcomp, mutoss to Suggests.

Net: R/multiple_testing.R grows from 916 to 1118 LOC because each thin-wrap function now carries both a CRAN-delegation arm AND an inline fallback (CRAN policy does not allow Suggests to be hard required, and qvalue is Bioconductor only). Function inventory is unchanged: 25 exports preserved (bonferroni, sidak, holm, hochberg, hommel, holm_sidak, benjamini_hochberg, bh, benjamini_yekutieli, by_fdr, storey_q, fisher_combined, stouffer_combined, tippett_combined, simes_combined, harmonic_mean_p, cauchy_combination, fixed_sequence, fallback_procedure, hierarchical_bonferroni, estimate_pi0, adjust_p_values, n_effective_tests, local_fdr, permutation_fwer, permutation_fdr, plus the print.morie_multiple_testing_result S3 method). All 85 tests/testthat/test-multiple_testing.R assertions pass on a fallback-only install.

R/did.R rewrite - delegate to did / DRDID / fixest / HonestDiD / bacondecomp / DIDmultiplegt

The DiD subsystem (~1,719 LOC) has been rewritten to forward to the canonical CRAN packages instead of carrying ~700 LOC of base-R fallback code:

The OLS-based wrappers (morie_did_2x2, morie_did_repeated_cross_section, morie_did_triple_difference, morie_did_continuous_treatment, morie_did_fuzzy) continue to use the in-package .morie_did_ols_robust_se helper because the specs are simple OLS / 2SLS regressions and a CRAN dependency for trivially-short OLS would be a regression. The same helper is reused by morie_did_wild_cluster_bootstrap, which remains base-R by design (fwildclusterboot is GitHub-only; see 0.9.5.12 NEWS).

Aggregators that consume DiD output and produce rmorie-specific tables (morie_did_aggregate_gt_att, morie_did_staggered, morie_did_parallel_trends_data, morie_did_test_parallel_trends, morie_did_placebo_test_*, morie_did_heterogeneous, morie_did_diagnostics) are unchanged.

Net: R/did.R shrinks from 1,719 to 1,463 LOC (-256, -15%); all 22 morie_did_* exports preserved; result-list shape is unchanged so downstream callers see the same fields.

DESCRIPTION: adds DRDID, HonestDiD, DIDmultiplegt to Suggests (fixest, did, bacondecomp, synthdid were already listed).

R/matching.R rewrite - delegate to MatchIt / cobalt / WeightIt

The matching subsystem (~2,183 LOC) has been rewritten to forward to the canonical CRAN packages instead of carrying ~950 LOC of base-R fallback code:

The carceral-domain helpers (morie_matching_att_matched / ate_matched / atc_matched, morie_matching_abadie_imbens_se, morie_matching_rosenbaum_bounds, morie_matching_doubly_robust, morie_matching_multi_treatment, morie_matching_longitudinal, morie_matching_quality, morie_matching_overlap, morie_matching_estimate_propensity / _trim_propensity / _common_support) are unchanged - they encode rmorie-specific output shapes (morie_match_result, morie_te_result) that the MRM / SIU / OTIS code paths depend on.

Net: R/matching.R shrinks from 2,183 to 1,586 LOC (-597, -28%); all 27 morie_matching_* exports preserved; behaviour-compatible for callers that already have MatchIt installed (which is the case for all matching tests in the rmorie suite).

DESCRIPTION: adds cobalt, designmatch to Suggests.

Breaking - CRAN-equivalent functions removed

To reduce code duplication with established CRAN packages and address rOpenSci feedback on fn_call_network_size, the following functions have been removed in favour of their well-maintained CRAN equivalents:

| Removed from rmorie | Use instead | |---|---| | cohens_d / morie_cohens_d | effectsize::cohens_d | | cramers_v / morie_cramers_v | effectsize::cramers_v | | eta_squared / morie_eta_squared | effectsize::eta_squared | | hedges_g / morie_hedges_g | effectsize::hedges_g | | morie_effective_sample_size | posterior::ess_basic or coda::effectiveSize | | morie_find_project_root | here::here() or rprojroot::find_root() | | fleiss_kappa | irr::kappam.fleiss | | kruskal_wallis | stats::kruskal.test (base R) | | shapiro_wilk | stats::shapiro.test (base R) | | anderson_darling | nortest::ad.test | | jarque_bera | tseries::jarque.bera.test |

Install the replacements with install.packages(c("effectsize", "irr", "nortest", "tseries", "here")).

morie_two_sample_t_test() / morie_chi_square_test() / morie_anova_one_way() now return list fields named cohens_d / cramers_v / eta_squared (was morie_cohens_d / morie_cramers_v / morie_eta_squared); the computation is inlined and unchanged. Internal callers of morie_find_project_root() now go through a private .morie_project_root() wrapper around here::here().

DESCRIPTION: adds here to Imports; adds effectsize, irr, tseries to Suggests.

rmorie 0.1.2

rmorie 0.1.0-4