Skip to contents

rmorie 0.9.8

  • Ecosystem connect: fast stats via the shared rmoriebricklayer C core; morie_bricklayer() assembler + morie_core.h sync-check.
  • Version 0.9.8 to match the morie family; source/UA URLs -> github.com/rootcoder007.

rmorie 0.9.6 (in development)

Bugfix: cluster-robust SE with empty cluster levels

  • .otis_cluster_se(): use sum(grp^2, na.rm = TRUE). A factor cluster carrying levels absent from a subset (e.g. per-year analysis of an individual-clustered panel) made tapply() emit NA for the empty clusters, yielding an NA SE that errored downstream (if (se > 0): “missing value where TRUE/FALSE needed”). Empty clusters contribute nothing, so they are now dropped. Fixes morie_otis_irm_dml() on per-year clustered runs. Regression test added.

Citation cleanup: remove Zenodo references

  • README.md: removed the “(DOIs will be re-added once we re-deposit on Zenodo.)” promise. The Zenodo deposits for the morie publication set were taken down; we are not committing to re-depositing.
  • inst/CITATION: removed the stale “also the R package source on Zenodo” comment.
  • NEWS.md: removed Zenodo DOI references from the historical 0.9.5.7 changelog entry.
  • No live DOI strings ever shipped in rmorie; this just removes the language that implied otherwise.

Phase 1 hotfix: drop wrappers for CRAN-archived packages

  • Removed morie_anchors_analyze (Phase 1.l) – upstream anchors was archived from CRAN on 2022-03-06 (check problems not corrected). pak resolver could not solve the dependency, blocking CI.
  • Removed morie_causal_mediation (Phase 1.h) – upstream causalweight was archived from CRAN on 2026-05-18 because its dependency LARF was archived. Same pak resolver failure.
  • DESCRIPTION: Suggests -= anchors, causalweight (35 wrapper extenders remain across Phases 1.k-1.n).
  • Both wrappers can be restored from git history (a9469ec, 4d78188) if the upstream packages return to CRAN.

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

  • New file R/extenders_nonparam.R with 6 wrappers (morie_locfdr_estimate, morie_fdr_qvalues, morie_quantile_reg, morie_np_kernel_reg, morie_dp_gaussian_mixture, morie_lcmm_latent_class)
  • DESCRIPTION: Suggests += dirichletprocess, fdrtool, lcmm, locfdr, np, quantreg
  • Tests in tests/testthat/test-extenders-nonparam.R

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

  • New file R/extenders_spatial.R with 9 wrappers covering variograms, kriging, copulas, kernel PCA, spectral clustering, meta-analysis, multivariate normal sampling and CDF (morie_geostat_variogram, morie_geostat_krige, morie_copula_fit, morie_copula_sample, morie_kernel_pca, morie_spectral_cluster, morie_meta_rma, morie_mvnorm_sample, morie_mvnorm_pmv)
  • DESCRIPTION: Suggests += copula, gstat, kernlab, metafor, mvtnorm
  • Tests in tests/testthat/test-extenders-spatial.R

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

  • New file R/extenders_rdd.R with 5 wrappers (morie_rdd_density_test, morie_rdd_local_randinf, morie_rdd_power_calc, morie_anchors_analyze, morie_anominate_ideal_points)
  • DESCRIPTION: Suggests += anchors, anominate, rdlocrand, rdpower (rddensity was already listed)
  • Tests in tests/testthat/test-extenders-rdd.R
  • Note: the rdpower wrapper is exported as morie_rdd_power_calc because morie_rdd_power already exists in R/rdd.R as a closed-form analytical power formula taking (n, tau, sigma); the simulation-based rdpower::rdpower surface is preserved alongside.

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):

  • morie_desc_cramers_v, morie_desc_kappa, morie_desc_winsorize, morie_desc_gini, morie_desc_atkinson -> DescTools::{CramerV, CohenKappa/KappaM, Winsorize, Gini, Atkinson}.
  • morie_performance_check_model, morie_performance_r2, morie_performance_check_collinearity, morie_performance_check_outliers -> performance::{check_model, r2, check_collinearity, check_outliers}.
  • morie_ppcor_partial, morie_ppcor_semipartial -> ppcor::{pcor, pcor.test, spcor, spcor.test} (matrix-wise when y/z are omitted, single-triple test otherwise).
  • morie_coin_independence, morie_coin_wilcoxon, morie_coin_oneway -> coin::{independence_test, wilcox_test, oneway_test}.
  • morie_randtests_runs, morie_randtests_turning_point, morie_randtests_bartels -> randtests::{runs.test, turning.point.test, bartels.rank.test}.

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:

  • morie_did_twoway_fe_weights(panel, group, time, treatment, outcome, type = "feTR", ...) – thin interface to TwoWayFEWeights::twowayfeweights (de Chaisemartin & D’Haultfoeuille, 2020). Returns an morie_did_twfe_diagnostics S3 list with the negative-weight count, the sum of weights, and the full twowayfeweights object as $raw. Complements morie_did_panel_fe (which estimates the TWFE coefficient itself) and morie_did_chaisemartin_dhaultfoeuille (which uses the same identification argument to deliver the DID-M estimator).
  • morie_did_synthdid_estimate(panel, unit, time, treatment, outcome, vcov_method = "placebo", ...) – thin interface to synthdid::synthdid_estimate (Arkhangelsky et al., 2021) under the synthdid-canonical name. Parallel to the existing morie_did_synthetic, which keeps the rmorie result-list shape; this extender surfaces the full synthdid object and the requested variance estimator (placebo, bootstrap, jackknife).

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:

  • morie_sensitivity_evalue(estimate, se, sd, type = "OLS", ...) – thin interface to the EValue::evalues.* dispatch family (evalues.OLS, evalues.RR, evalues.OR, evalues.HR, evalues.MD). Pairs with the typed e_value_rr/_or/_hr/_d wrappers, which call the same backend but with a fixed scale.
  • morie_sensitivity_tipping_point(estimate, smd, r2, ...) – thin interface to tipr::tip for unmeasured-confounder tipping points. Pairs with tipping_point_analysis (which targets missing-data sensitivity rather than unmeasured confounders).
  • morie_sensitivity_omitted_var_bias(model, treatment, benchmark_covariates, ...) – thin interface to sensemakr::sensemakr on a fitted lm. Pairs with omitted_variable_bias (closed-form Cinelli-Hazlett robustness value when only estimate + se + dof are available).
  • morie_sensitivity_konfound(estimate, se, n, n_covariates, ...) – thin interface to konfound::pkonfound for the Frank et al.
    1. percent-bias-to-invalidate and impact-threshold-of-a- confounding-variable (ITCV).

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:

  • morie_causal_impact(data, pre_period, post_period, model_args) -> CausalImpact::CausalImpact() (Brodersen et al. 2015 Bayesian structural time-series intervention analysis).
  • morie_causal_weighting(data, treatment, covariates, method, estimand, ...) -> WeightIt::weightit() (full method palette: glm / cbps / ebal / ps / energy / optweight).
  • morie_causal_robust_se(model, type, cluster, ...) -> sandwich::vcovHC() / vcovHAC() / vcovCL() (HC0-HC5, HAC, one-way cluster-robust variance).
  • morie_causal_mediation(y, d, m, x, trim, boot, ...) -> causalweight::medweight() (semiparametric IPW direct / indirect effect decomposition).

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):

  • bootstrap() – nonparametric bootstrap now delegates to boot::boot (stratification via strata=) and boot::boot.ci for percentile / basic / normal / bca CIs. The studentized CI path and the cluster resampling path remain inline because boot::boot.ci(type = "stud") requires a precomputed variance estimator and boot::boot does not expose cluster-of-clusters resampling for the rmorie statistic(data) -> scalar signature.
  • parametric_bootstrap() – delegates to boot::boot(sim = "parametric") with an MLE / ran.gen pair built from the requested distribution.
  • block_bootstrap() – moving / stationary blocks delegate to boot::tsboot(sim = "fixed" / "geom"); the circular-block path stays inline because boot::tsboot does not expose a circular sim mode.
  • jackknife() – delegates to bootstrap::jackknife when installed (rmorie reconstructs pseudovalues / influence values around the returned jack.values).
  • permutation_test() / paired_permutation_test() – inline shuffle loops retained (the rmorie API returns the full null distribution which downstream MRM code consumes); coin’s oneway_test(distribution = "approximate") and symmetry_test(distribution = "approximate") are cross-referenced as the canonical CRAN equivalents.
  • bootstrap_632() – inline .632 / .632+ retained because the rmorie API takes naked model_fn / score_fn callables; ipred::errorest(estimator = "632plus") is cross-referenced.
  • repeated_cv() / leave_one_out_cv() – delegate to rsample::vfold_cv for fold construction when no stratification or grouping is requested; caret::trainControl and rsample::loo_cv cross-referenced.

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

  • subsampling() – Politis-Romano-Wolf rate scaling over a user-supplied statistic(data); np::npsubsample is closest but is kernel-specific.
  • delete_d_jackknife() – generalised jackknife with custom max_subsets enumeration cap; resample::jackknife is cross-referenced.
  • wild_bootstrap() – returns the full resampled coefficient distribution; sandwich::vcovBS (variance only) and fwildclusterboot::boottest (p-value only) cross-referenced.

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

  • morie_boot_run(data, statistic, R, strata, ...) – direct boot::boot bridge with rmorie-style statistic(data) -> scalar adapter.
  • morie_boot_basic_ci(boot_obj, type, conf) – direct boot::boot.ci bridge returning tidy list(perc = c(lo, hi), bca = c(lo, hi), ...).
  • morie_rsample_bootstraps(data, times, ...) – direct rsample::bootstraps bridge returning an rset.
  • morie_simpleboot_two(x, y, statistic, R, ...) – direct simpleboot::two.boot bridge for two-sample bootstrap of a scalar statistic.

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):

  • cauchy_combination() – Liu and Xie 2020; ACAT is GitHub-only.
  • hierarchical_bonferroni() – rmorie-specific stage-list return shape; gMCP covers the concept with a different graphical API.
  • local_fdr() – Efron empirical-Bayes KDE shape that locfdr does not match in return structure.
  • permutation_fwer(), permutation_fdr() – step-down max-T and empirical-null-p FDR over user-supplied null matrices; no CRAN function exposes the same API.
  • adjust_p_values() – front-end dispatcher across the rmorie wrappers; consumed by stat_commands.

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.9.5.12 - 2026-05-25

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

  • Removed fwildclusterboot from Suggests and removed the .morie_did_have_fwildboot() helper + the if (.morie_did_have_fwildboot()) { fwildclusterboot::boottest(...) } branch in morie_did_wild_cluster_bootstrap(). The function now goes straight to the base-R Rademacher/Webb wild-cluster bootstrap (which already existed as the fallback and mirrors the Python implementation; no math change for any caller).
  • Reason: pak’s resolver does not reliably recurse through a Remote’s own Remotes. 3MMM.40 added s3alfisc/fwildclusterboot and 3MMM.40b added s3alfisc/summclust, but the resolver still reported summclust: Can't find package called summclust – so the recursive-Remote pattern is structurally fragile. Following the same “drop optional CRAN-archived/GitHub-only deps” pattern used for rdd in 3MMM.40.
  • Remotes: now lists only synth-inference/synthdid, which has no GitHub-only transitive Imports.