Skip to content

Prepare BREAD 0.99.0 for Bioconductor submission - #1

Open
BacZemin wants to merge 17 commits into
mainfrom
polish-for-release
Open

Prepare BREAD 0.99.0 for Bioconductor submission#1
BacZemin wants to merge 17 commits into
mainfrom
polish-for-release

Conversation

@BacZemin

@BacZemin BacZemin commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Prepares BREAD for Bioconductor submission as 0.99.0. 8 commits, 65 files, +1839/−104.

Not merged, not tagged, not released, not submitted — see "Deliberately not done".

CI status

Workflow Result Run
R-CMD-check (ubuntu / R release) ✅ success 31299673060
bioc-check (Bioc devel container) ✅ success 31299673073

Neither workflow existed before this branch. R CMD check on the Bioconductor
devel container reports Status: OK — 0 errors, 0 warnings, 0 notes.

Devel toolchain, read from the container rather than assumed:
R 4.6.1 (2026-06-24) · Bioconductor 3.24 · BiocCheck 1.49.30 · x86_64-pc-linux-gnu

Test suite: 284 passing, 0 failures. Coverage: 74.73%
(classify.R and classes.R at 100%; fit_brms.R at 0% because the Stan test
is skipped where there is no toolchain).

BiocCheck: baseline → now

Baseline on unmodified main was 3 ERRORS | 4 WARNINGS | 11 NOTES.
Now 1 ERROR | 1 WARNING | 10 NOTES, and both remaining items are outside
code control.

Baseline finding Status
ERROR New package version not x.99.z (0.0.0.9000) ✅ fixed → 0.99.0
ERROR <80% of exported man pages have runnable examples ✅ fixed → 17/17
ERROR Maintainer email not found on the Bioconductor Support Site needs you
WARNING Version starts with non-zero value ✅ fixed
WARNING set.seed() in package code (R/methods.R:60) ✅ fixed → withr::with_seed()
WARNING Empty/missing \value sections (6 man pages) ✅ fixed
WARNING Package already exists on CRAN decision needed — see below
NOTE Update R version dependency ✅ fixed → Depends: R (>= 4.4.0)
NOTE Consider biocView Classification ✅ added
NOTE CITATION file not found ➖ deliberate, see below
NOTE Add maintainer ORCID needs you
NOTE ×4 (suppressWarnings, function length, indentation, dontrun) ➖ deferred, reasons below

R CMD check separately lost two NOTEs: non-standard top-level files and the
unused GenomeInfoDb import. Only the environment-only qpdf warning and
"unable to verify current time" remain on the HPC, and neither reproduces on CI.

⛔ Decision needed: the package name collides with CRAN

BiocCheck's checkIsPackageNameAlreadyInUse() compares
tolower(pkgName) %in% tolower(CRAN packages)case-insensitive by design.
CRAN has bread v0.4.1,
"Analyze Big Files Without Loading Them in Memory", entirely unrelated.

This is not a BiocCheck quirk. On case-insensitive filesystems (macOS, Windows)
BREAD and bread cannot coexist in one library, so the rule is real.
Bioconductor's stated remedy — "must be removed from CRAN before the next
release" — assumes the CRAN package is yours. It is not. The practical
outcome is that Bioconductor will require a rename.

A rename touches: the GitHub repo name, the pkgdown URL, library() calls in
both vignettes, the thesis text, and the "bread & brie" pairing with the
sibling BRIE package. Worth knowing: no CRAN or Bioconductor package is
named brie
— only BREAD collides.

I did not act on this. It is the single decision that should be made before
anything else here is merged, because a rename would touch most of this diff.

⛔ Other things only you can do

  1. Register on the Bioconductor Support Site with the maintainer email in
    DESCRIPTION (jaemin.park@vai.org) — https://support.bioconductor.org/accounts/signup/.
    This is the last remaining BiocCheck ERROR.
  2. Subscribe to bioc-develhttps://stat.ethz.ch/mailman/listinfo/bioc-devel.
    BiocCheck cannot verify this without admin credentials (NOTE).
  3. Supply your ORCID and I will add
    comment = c(ORCID = "...") to Authors@R. I did not invent one — a
    fabricated identifier in a public package is worse than a missing one.

What changed

CI and packaging

  • R-CMD-check.yaml — ubuntu/release only for now; add macOS and Windows once
    it has been green for a while.
  • bioc-check.yamlR CMD buildR CMD checkBiocCheck(new-package = TRUE)
    in bioconductor/bioconductor_docker:devel. The devel R/Bioc versions are
    printed by the job, never hardcoded. It fails on any BiocCheck ERROR or
    WARNING beyond the two known-blocked ones
    , so it is a real regression gate
    rather than a green badge.
  • pkgdown.yaml untouched — it triggers only on push: main, so the live site
    was never rebuilt from this branch.
  • 0.99.0, Depends: R (>= 4.4.0), Date, biocView Classification,
    three-sentence Description.

Examples — the main event. All 17 exported objects now have runnable
examples on the packaged EPICv2 data. A full 500-region fit is ~0.7 s, so each
example is self-contained rather than sharing a cached fit. Three traps the
examples had to route around, all of which would have shipped as broken
documentation:

  • validate_bread_input() and summarize_features() default to
    assay_name = "M", but the packaged assay is "betas" — only fit_bread()
    auto-detects, so those examples pass both arguments explicitly.
  • plot_region_posterior() and posterior_draws() default to region_id = NULL,
    which means 500 facets and 2,000,000 rows respectively. Every example names a
    region.
  • 2 of the 500 regions fail to fit, so the plotting examples pick a region
    defensively with a fallback.

API

  • posterior_summary() accepts a BreadFit directly instead of requiring
    fit@model.
  • Added a BreadResults() constructor and show method. The class was
    previously unconstructable
    — nothing in the package ever called
    new("BreadResults", ...), and it had no show method. See the open
    question below.
  • Removed report_feature_set(), a stop("not yet implemented") stub that was
    shipping with a live man page. plot_feature_set() covers the same ground.
  • posterior_draws() uses withr::with_seed() instead of set.seed(). This
    fixes a real defect as well as the BiocCheck warning: the bare set.seed()
    leaked its reseed into the caller's RNG stream. Note withr::local_seed()
    does not restore state in withr 3.0.2 — verified, hence with_seed().

Tests — 7 new files covering the six R files that had none, including
posterior.R and classify.R, the statistical core.
test-extdata-contract.R pins the packaged data shape so a rename or dropped
colData column surfaces as a named failure instead of an opaque
R CMD check error in 12 examples at once.

DocsREADME.md is now generated from README.Rmd. It previously
hard-coded 76 / 39 / 385 as a hand-typed comment, and an earlier draft had
already shipped the wrong classification labels; those counts are now
generated. Added .github/CONTRIBUTING.md, SUPPORT.md,
CODE_OF_CONDUCT.md (adopting the Bioconductor CoC), and issue templates that
route usage questions to the Bioconductor support site. Fixed _pkgdown.yml,
which claimed the backend fit helpers were exposed (they are internal) and
still advertised 0.0.0.9000.

Two things worth a second look

CLAUDE.md was being packaged. The baseline R CMD check listed it under
non-standard top-level files — it was neither .gitignored nor
.Rbuildignored, so it was going into every built tarball. Both are fixed, and
I audited the branch history to confirm nothing leaked into a commit.

GenomeInfoDb is a real dependency. R CMD check reported
"Namespace in Imports field not imported from", so I dropped it — and both CI
workflows immediately failed to build vignettes. On Bioc devel the Seqinfo
class has moved to its own package but is still registered as belonging to
GenomeInfoDb, so findOverlaps()merge(seqinfo)methods::is() calls
.requirePackage("GenomeInfoDb"). The NOTE was about the namespace, not the
dependency. It is restored, and now genuinely imported:
map_probes_to_features() already told users to check seqlevels() when
nothing overlapped, so it reports them. The HPC preflight missed this because
GenomeInfoDb is installed there as a transitive dependency.

Deferred, with reasons

  • inst/CITATION removed. BiocCheck warns when a CITATION has no doi,
    and Bioconductor's guidance is to ship one only once a preprint or
    publication exists. citation("BREAD") still works, generated from
    DESCRIPTION. Add it back with bibentry(doi = ...) when there is a DOI.
  • Depends: R (>= 4.4.0) not bumped to 4.6.0. BiocCheck raises this only
    as a NOTE. Bumping it would make the package uninstallable on the HPC
    (R 4.4.3) and break the preflight loop. Worth revisiting at submission.
  • 11 functions over 50 lines (fit_bread is 125). NOTE only; refactoring
    the main entry point unattended was not a good trade.
  • 762 lines not on 4-space indents. A whole-package styler run would bury
    this diff.
  • 6 suppressWarnings/suppressMessages. Each is deliberate; the one in
    map_probes_to_features() is now explained in a comment.
  • \dontrun{} on bread_kycg(). BiocCheck suggests donttest instead,
    but donttest blocks are run by R CMD check, and that call downloads
    KnowYourCG reference databases. The surrounding fit does run.
  • macOS/Windows CI. Add once ubuntu has been stable.
  • brms test skipped on CI. Runners install brms and rstan but lack the
    RcppEigen headers Stan needs, so the test cleared every
    skip_if_not_installed() and then died with "Eigen not found". A full Stan
    toolchain per run costs ~10 minutes and is flaky. It still runs on the HPC.

Open question

BreadResults is a thin wrapper with no consumer anywhere in the package —
its only plausible caller was the report_feature_set() stub this PR deletes.
I gave it a constructor and a show method, which is additive and reversible.
The alternative is deleting the class before 0.99.0 freezes the API, which
is arguably the better long-term call. It is announced in NEWS.md and
_pkgdown.yml, so it is your decision, not one to make unattended.

Deliberately not done

No tag. No GitHub release. No Zenodo. No issue on Bioconductor/Contributions.
Not merged. origin/main is untouched at cc229eb.

Repo settings changed outside this branch (the only such changes):
homepagehttps://baczemin.github.io/BREAD/ (it pointed at the repo
itself), 7 topics added, and the empty wiki and projects tabs disabled.

BacZemin added 17 commits August 9, 2026 01:43
Bioconductor requires new submissions to be versioned x.99.z, and until now
nothing verified the package on a clean machine -- the only workflow was
pkgdown.

- R-CMD-check.yaml: ubuntu/release only for now; more platforms once green.
- bioc-check.yaml: runs R CMD check + BiocCheck(new-package = TRUE) in the
  bioconductor/bioconductor_docker:devel container. The devel R/Bioc versions
  are printed by the job rather than hardcoded anywhere.
- DESCRIPTION: 0.99.0, Depends: R (>= 4.4.0), drop the unused GenomeInfoDb
  import (R CMD check NOTE).
- .Rbuildignore: data-raw, build_preview and CLAUDE.md were all being packaged
  into the tarball.
- .gitignore: keep CLAUDE.md and tools/teaching out of a public repo.
BiocCheck ERROR: at least 80% of man pages documenting exported objects must
have runnable examples. Only bread_kycg had one, and it was a dontrun block
over undefined objects.

- Every exported object now has an example built on the packaged EPICv2 data.
  A full 500-region fit is ~0.7s, so each example is self-contained rather
  than sharing a cached fit. Examples that call the lower-level helpers pass
  assay_name = "betas" / input_scale = "Beta" explicitly, because only
  fit_bread() auto-detects them. Plot and draw examples always name a region:
  the NULL default would facet 500 panels / return 2M rows.
- bread_kycg keeps a dontrun block for the enrichment call itself, which
  downloads KnowYourCG reference databases, but the surrounding fit now runs.
- posterior_summary() accepts a BreadFit directly, so callers no longer reach
  into the model slot.
- Add a BreadResults() constructor and show method. The class had no way to
  construct one anywhere in the package.
- Remove report_feature_set(), an unimplemented stop() stub;
  plot_feature_set() covers the same ground.
- posterior_draws() uses withr::with_seed() instead of set.seed(). BiocCheck
  flags set.seed in package code, and the bare call also leaked its reseed
  into the caller RNG stream. (with_seed, not local_seed: the latter does not
  restore the previous state in withr 3.0.2.)
- Add missing \value sections flagged by BiocCheck.
…xtdata

Six R files had no test file at all, including posterior.R and classify.R --
the statistical core.

- test-classify.R drives the decision rule with hand-built posterior tables so
  the cutoff boundary is exact: >= is inclusive, a stricter cutoff can only
  move regions to inconclusive, NA rows never yield NA classifications.
- test-posterior.R pins the 13-column contract, checks that a wider ci widens
  intervals without moving point estimates, that p_pos + p_neg == 1, and that
  the new BreadFit fast-path is identical to passing the model list.
- test-methods.R covers accessor/name alignment, seed reproducibility, and
  that posterior_draws() restores the caller RNG state.
- test-classes.R pins the S4 slot layout, which the plotting helpers and
  accessors depend on by name.
- test-utils.R covers the M/beta round trip, boundary clamping, and the
  documented assay-name priority order.
- test-kycg.R covers argument validation only -- no network calls.
- test-extdata-contract.R pins the packaged data shape. Every new example is
  written against those two objects, so a rename or a dropped colData column
  would otherwise surface as an opaque R CMD check failure.

284 tests pass.
The README hard-coded its example output as a hand-typed comment, and an
earlier draft had already shipped the wrong classification labels. It is now
knitted from README.Rmd, so the 76/39/385 counts are generated rather than
asserted.

- inst/CITATION, picking the version up from DESCRIPTION. No DOI yet; add one
  via bibentry(doi = ) once there is a preprint.
- .github/CONTRIBUTING.md, SUPPORT.md, and CODE_OF_CONDUCT.md (adopting the
  Bioconductor Code of Conduct), plus issue templates that route usage
  questions to the Bioconductor support site.
- NEWS.md: heading is now a bare version, which the Bioconductor markdown NEWS
  parser requires.
- _pkgdown.yml: the reference section claimed the backend fit helpers were
  exposed, but they are internal and unexported; the news block still
  advertised 0.0.0.9000.
Dropping GenomeInfoDb from Imports broke vignette building on both CI
workflows: on Bioconductor devel the Seqinfo class has been split into its own
package but is still registered as belonging to GenomeInfoDb, so
findOverlaps() -> merge(seqinfo) -> methods::is() calls
.requirePackage("GenomeInfoDb") and fails if it was never installed.

R CMD check's "Namespace in Imports field not imported from" NOTE was about
the namespace, not the dependency -- the dependency is real and indirect. It
is now a genuine import: map_probes_to_features() already told users to check
seqlevels() when nothing overlapped, so the error now reports them instead of
just naming the function.

The HPC preflight did not catch this because GenomeInfoDb is installed there
as a transitive dependency of the current GenomicRanges.
BiocCheck on Bioc devel reported "Unable to read CITATION file". The file
fell back to packageVersion("BREAD") when meta was NULL, but BiocCheck
validates the CITATION against an uninstalled package, so that call errored.
The fallback is now a literal. It passed on the HPC only because a stale
BREAD 0.0.0.9000 happened to be installed there.

Also:
- DESCRIPTION Description expanded to three sentences (BiocCheck NOTE),
  covering the two backends and the knowYourCG hand-off.
- bioc-check now fails on any BiocCheck ERROR or WARNING beyond the two that
  cannot be resolved in code (support-site registration; the case-insensitive
  name collision with CRAN's unrelated 'bread'). Previously the workflow
  reported findings but always went green.
BiocCheck on devel warns when a CITATION file has no doi argument, and
Bioconductor's own guidance is to include one only once a preprint or
publication exists. There is none yet, so the file goes; citation("BREAD")
still works, generated from DESCRIPTION.

Add it back with bibentry(doi = ...) once there is a preprint or a Zenodo DOI.

DESCRIPTION gains a Date field so the generated citation carries a year
instead of (????); the README renders citation() live and was showing the
placeholder.
R-CMD-check failed on test-fit-brms.R with "Eigen not found". The existing
skip_if_not_installed("brms") / ("rstan") guards all pass on GitHub runners
-- both packages install fine -- but Stan then cannot compile a model because
the RcppEigen headers are absent, so the test ran and errored.

Installing a working Stan toolchain on every CI run costs about ten minutes
and is flaky, so the test is skipped on CI instead. It still runs on the HPC,
and on build systems that do not set CI, which is where the brms backend is
actually exercised.
p_gt_delta and p_lt_neg_delta read as p-values, which is exactly the
inference they are not. Renamed to prob_hyper / prob_hypo, matching the
classification factor levels, and p_pos / p_neg to prob_pos / prob_neg.

These are posterior probabilities of the parameter given the data --
prob_hyper = P(effect > +delta), prob_hypo = P(effect < -delta) -- not
tail probabilities of a statistic under a null.

Clean break, no deprecation shim: 0.99.0 is unreleased.
Several GRanges may share one name -- the only way to pin a region to an
exact probe set, since a bounding interval sweeps in neighbours. split()
handled this correctly all along but the counters did not:

  n_features_in    counted ranges (length(features))
  show()           printed length(object@features) as n_regions

which produced "n_regions: 788 (of 790 input)" for what was really 30
regions built from 790 probes. Results were always right; only the
counters lied.

Adds .make_toy_features_dup() (3 ranges, 2 regions) and pins the
invariant n_features_out == nrow(results(fit)).
The headline is a fourth classification level. `inconclusive` was absorbing
two different situations: a region whose posterior sits tightly inside the
ROPE (strong evidence of no change) and one whose posterior says nothing at
all. Collapsing them throws away the single claim a p-value structurally
cannot make. The mousearray_609G CArG result is the case in point --
REGULON_promoter carries P(|effect| < delta) = 0.958 and was labelled
`inconclusive`, indistinguishable from noise.

classification levels are now hypermethylated / hypomethylated / unchanged /
inconclusive. `unchanged` is inserted third so levels()[1:2] stay the
directional pair. Membership of the two directional classes is bit-identical
for any prob_cutoff > 0.5 -- the new level strictly partitions the old
`inconclusive` bucket -- so directional filters are unaffected.

posterior_summary() gains six columns: prob_rope plus a beta-scale
translation (ref_beta, mean_dbeta, dbeta_lo, dbeta_hi, delta_beta). The
translation uses one linearisation multiplier per region, anchored at the
region's own mean methylation, so the beta comparison can never contradict
the M-scale classification printed beside it. delta stays M-scale only: a
beta-defined threshold is necessarily per-region and would silently become a
20-fold wider ROPE at the methylation extremes. bread_delta_beta() and
bread_delta_m() convert explicitly instead.

Also:

* rope_cutoff, separate from prob_cutoff but defaulting to it. Equivalence
  needs the whole posterior inside +/-delta, a far stricter demand than a
  directional call; at n = 6+6 a shared knob ships the feature unusable.
* ci is now a fit_bread() argument. It was hardcoded at 0.95, distinct from
  prob_cutoff but unreachable.
* Matrix input. openSesame() returns a matrix and sesameData examples are
  list(betas=, sampleInfo=); BREAD rejected both, so the sesame workflow
  died at step one. New bread_se() / .as_bread_se() accept them with
  colData plus either rowRanges or platform. The platform is never inferred
  from probe IDs -- cg-numbers are shared across HM450/EPIC/MM285 and a
  wrong guess yields wrong coordinates with no error. EPICv2 suffix
  mismatches get a specific diagnosis.
* refit_bread(). Permutation calibration needs the region matrix computed
  once and only the fit repeated; without a public entry point the only
  route was BREAD:::fit_bread_summary(). Re-thresholding short-circuits the
  model fit entirely.
* Rank-deficient designs now warn. fit_summary adds Lambda0 = 0.01*I before
  the Cholesky, so collinear designs never errored -- they silently returned
  prior-driven estimates. Every caller so far hand-rolled its own qr() guard.
* bread_kycg(): the default pattern required a literal . after TFBS, so
  it could not match KYCG.MM285.TFBSconsensus.20220116 and mouse users got a
  silently empty data.frame. Now a per-platform table, a warning that lists
  what is available, and mtc_by_group/mtc_method passthrough filtered
  against the installed signature. Also fixes an rbind error reachable today
  whenever one classification level yields a stub and another a real table.
* The toy fixture had sex perfectly collinear with group, so every test
  using ~ group + sex was silently fitting a rank-deficient design.

412 tests pass, up from 284.
Documents the four-level classification, the six new results() columns,
the n_features_in region-vs-range fix, the fit_bread() first-argument
rename, and the palette change, all as breaking changes -- 0.99.0 is
unreleased so they land without a deprecation period.
README gains an explicit section on the unchanged class and on why delta
is M-scale only, plus the matrix-input and refit_bread workflows. The vitc
vignette n=2 paragraph is rewritten rather than patched: at n=2 almost
nothing reaches prob_rope >= 0.95 either, so those regions are unresolved
rather than shown to be flat -- which is a sharper statement than the old
undifferentiated inconclusive bucket, and the best advertisement for the
feature.
…nchanged

At n=4 nothing reaches prob_rope >= 0.95, which is the honest result and
the concrete argument for rope_cutoff being a separate knob. Better shown
than hidden -- it also demonstrates the unresolved-vs-flat distinction the
class exists to draw.
…d README

- README described `n` as the probe count per region; it is the number of
  samples contributing to the fit after NA-dropping. Probe counts are in
  `mapping$n_probes`. Say so in posterior_summary()'s @return too, which
  had listed `n` without defining it.

- Document how far the first-order beta translation drifts from an exact
  back-transform: median 0.0005 and p99 0.021 in beta units on the packaged
  vitamin C example, ~2% relative below |dM| 0.25 rising to ~10% above 0.5.
  No classification is affected, but mean_dbeta should not be quoted to
  three decimals for a strongly changing region.

- README.md was stale: it still documented the three-level API and none of
  prob_rope / unchanged / the beta columns, because 5f60905 and 4c3c3c0
  edited README.Rmd without rerunning build_readme(). Rebuilt.

- ROPE interval was written \[-delta, +delta\]; pandoc read the escaped
  brackets as LaTeX and emitted $$..$$ display math into the GFM output.
  Reworded to avoid the brackets.
The conjugate update a_n = a0 + n/2 makes nu = 2*a_n a function of the
sample size alone and never of the number of coefficients p. That is the
literal NIG result and correct given the stated prior, but the default
prior (Lambda0 = 0.01 I) was only ever meant to be uninformative, and the
reference-prior answer -- the one lm() gives -- is n - p. The posterior
scale is too small by exactly sqrt(n / (n - p)), so the error grows with
p/n and bites hardest on interaction designs at small n.

Measured on the packaged vitamin C data with ~ condition + passage
(n = 8, p = 3): BREAD reported df = 8.002 and scale 0.04715 where lm gives
df = 5 and se 0.05559. Switching to df_mode = "residual" moves 24 of 93
hypermethylated and 5 of 50 hypomethylated regions to inconclusive -- 20%
of the directional calls were an artefact of the optimistic df.

Two changes:

* fit_bread(df_mode = c("conjugate", "residual")). "conjugate" stays the
  default so existing results reproduce; "residual" uses
  a_n = a0 + (n - p)/2 and reproduces the classical t_{n-p} marginal,
  matching lm() exactly as Lambda0 -> 0 (tested at lambda0 = 1e-8).
  Recorded in fit@params$df_mode and fit@model$df_mode. Ignored by the
  brms backend, which samples sigma^2 directly.

* Regions with n <= p are dropped with
  error = "n <= number of coefficients" rather than fitted. With no
  residual information the residuals are identically zero, b_n collapses
  to b0, and the scale collapses with it: on pure noise at n = p = 4 the
  old path returned a scale ~7x tighter than at n = 8 and a credible
  interval excluding zero. Only n < 2 was guarded before.

Also warns once per fit -- not once per region -- when any fitted region
has fewer than 3 residual degrees of freedom.

test-classes.R pins the fit@model field names as a deliberate contract;
updated for the added df_mode field.
man/figures/logo.png is picked up automatically by pkgdown for the navbar
brand, the home-page header and the og:image card, so _pkgdown.yml needs no
change. The README uses the anchor-wrapped form; pkgdown strips both the
bare and anchored variants from the homepage body (tweak_homepage_html
matches .//h1/img and .//h1/a/img) before inserting its own sidebar logo, so
the logo is not duplicated there.

The vignettes embed the logo as a base64 data URI via knitr::image_uri()
rather than linking ../man/figures/logo.png. A plain relative link would
work in the tarball -- html_vignette is self-contained, so pandoc inlines
it -- but it breaks on the pkgdown site: copy_article_images() only copies
resources whose path is a child of the vignette directory, and a parent-
escaping path is dropped. Resolving the file at knit time sidesteps this;
pkgdown's check_missing_images() skips any src with a non-empty URI scheme
and handles data:image explicitly in its alt-text check.

Verified: R CMD build ships BREAD/man/figures/logo.png and nothing from
data-raw/ or pkgdown/; an isolated html_vignette render of the logo chunk
emits one data URI, zero leftover relative paths, and the alt attribute.

README.md was hand-mirrored rather than regenerated -- the edit is a single
line above every code chunk and github_document passes raw HTML through
verbatim, so build_readme() would only have re-run the live model fits and
churned unrelated numbers into a logo commit.
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.

1 participant