Exploratory Subgroup Identification in Survival and GLM Outcomes
- CRAN checks, method
Method
Checks and health
CRAN runs every current package through
R CMD checkon a set of machines and publishes a result for each one. The health shown on a package page comes from these results alone.- Problems
- Notes alone never count against a package, but a warning, an error or a failure on any platform is a problem. Open CRAN deadlines are a fact of their own, shown as a clock after the mark, so the mark always says what the checks found.
- Checks only
- Health reflects CRAN's check results and nothing else. Even a package with no tests, no coverage or no recent release can have every platform OK.
- Once a day
- Results are collected once a day from files CRAN publishes. Each platform is one machine set-up, named by its R version, operating system, architecture and compiler, such as r-devel-linux-x86_64-fedora-clang.
- Platforms counted
- The 13 in 3 of 13 is the number of platform rows CRAN published for that package on the day of collection. The set of machines changes over time, so the number is not fixed, and a package missing from a platform counts as neither passing nor failing there.
- All OK13 platforms
- CRAN 30-day downloads, method
- 396+23.8% up on the 30 days before, the better direction
- Dependent packages, method
Method
Reverse dependencies
Dependent packages are other packages that list this one under
Depends,ImportsorLinkingToin theirDESCRIPTIONfile. Those fields list the packages a package needs to install, so dependents break if this one is archived or broken.- As declared
- The counts follow the declarations as written, not whether a package uses the other one when it runs.
- Suggests apart
- Packages that list this one only under
Suggestsinstall and run without it, and use it for tests, examples or an optional feature. They are counted as Suggested by, never among the dependents, and a package that also lists it under one of the three fields is a dependent and is not counted again. - Zero
- Zero dependents means no current CRAN package declares a need for this one, though some may suggest it. On 28 Oct 2026, 19,572 of the 25,583 current CRAN packages had no dependent package.
- 0none suggest it
- Test coverage, method
Method
Test coverage
Test coverage is measured by downloading each CRAN package's current source file, installing its dependencies, building it and running its tests under covr.
- Almost half of CRAN has no tests to run
- Only CRAN packages are measured. Many have no percentage, most often because the package has no tests, and that blank is a recorded outcome, not missing data.
- NOT_CRAN
- Tests run with NOT_CRAN=true, so tests that skip themselves on CRAN run here, and the figure can differ from what CRAN's own checks see.
- Current version only
- Only the current version is measured, and a new version on CRAN is measured again. Older rows are kept but never filled in later. This is one package's run.
- Never 0%
- On a package page three states stay apart: measured, no tests, and not measured. Neither of the last two is ever shown as 0%.
- 38%of lines run by tests
- Advisories, method
Method
Security advisories
Advisories come from the R Consortium advisory database, a community record of security problems in R packages, as OSV publishes it.
- The copy
- The record is read once a day. The data is published under the Apache License 2.0 and is credited on the advisories list.
- Box under the name
- Under the package's name, a box names any advisory that affects the current release, with its fix or that there is none.
- Ranges
- Advisories state ranges, such as from 0.9.12 up to but not including 1.8.8. Each range is checked against every version CRAN has published, using the version rules R itself uses, so a release that came out after the advisory was written is still caught by its range.
- Not the package
- The rating is for the library flaw itself, not for how exposed the R package is, and it is never added up into a figure for the package.
- None known
About
Method, About Method Licence figures come from the Licences
License field of each package's DESCRIPTION file, read the way R itself reads it. No licence file is opened.tools::analyze_license() and R's own licence database, as CRAN's checks read it.| is read, so one string can offer two families.
Implements statistical methods for exploratory subgroup identification in clinical trials. Provides tools for identifying patient subgroups with differential treatment effects using machine learning approaches including Generalized Random Forests (GRF), LASSO regularization, and exhaustive ...
Full description
Implements statistical methods for exploratory subgroup identification in clinical trials. Provides tools for identifying patient subgroups with differential treatment effects using machine learning approaches including Generalized Random Forests (GRF), LASSO regularization, and exhaustive combinatorial search algorithms. Supports survival endpoints (Cox proportional hazards), binary outcomes (log odds ratio, log relative risk, risk difference), continuous outcomes (mean difference), and count / rate outcomes (log incidence rate ratio via Poisson, quasi-Poisson, or negative-binomial GLMs with optional person-time offset). Features bootstrap bias correction using infinitesimal jackknife methods to address selection bias in post-hoc analyses. Designed for clinical researchers conducting exploratory subgroup analyses in randomized controlled trials, particularly for multi-regional clinical trials (MRCT) requiring regional consistency evaluation. Methods are described in Leon et al. (2024) <doi:10.1002/sim.10163>. Post-selection inference for the identified subgroup follows León and Anderson (2026) <doi:10.48550/arXiv.2609.38361>.
- Maintainer
- Larry Leon
- Licence
- MIT + file LICENSE
- Latest release
- 10 Oct 2026
- First release
- 23 Mar 2026
More details
- Releases
- 2
- Needs compilation
- No
- Needs R
- >= 4.1.0
- Config/roxygen2/version
- 8.1.0
- Config/testthat/edition
- 3
- SystemRequirements
- Quarto command line tools (https://github.com/quarto-dev/quarto-cli)
Subjects (1) Method, SubjectsMethod
Subjects and collections
Subjects are the site's own grouping of CRAN packages, found by clustering. Collections are sets of packages that communities declare, such as the tidyverse.
- Subjects
- Subjects are found by clustering the words of current CRAN packages and the packages they use. No one edits them by hand.
- Collections
- Collections are sets that communities declare, through a package that installs the set or an organization on GitHub. The site finds them by rules.
- Who made each
- Subjects are marked Site and collections Community. Subjects, collections and task views are never mixed in one list.
- The day of the data
- Subjects and collections were last worked out on 22 Oct 2026.
Cite
Package
Run in R for the authors' preferred citation:
citation("forestsearch")Leon, L. (2026). forestsearch: Exploratory Subgroup Identification in Survival and GLM Outcomes (Version 0.4.0) [Computer software]. https://doi.org/10.32614/CRAN.package.forestsearch
About
This package has no citation file, so citation() returns this entry built from DESCRIPTION.
R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
Balamuta, J. J. (2026). R Observatory: Metrics for forestsearch version 0.4.0 [Data set]. HJJB, LLC. Data release v2026-10-28. https://doi.org/10.5281/zenodo.21843040
About
From data release v2026-10-28, which the citation names so these numbers can be found later.
Health
All 13 check platforms pass.
r-devel-linux-x86_64-debian-clangThe unreleased R on Linux, x86_64, debian-clang
OK
- Version checked
- 0.4.0
- Time taken
- 636 s
r-devel-linux-x86_64-debian-gccThe unreleased R on Linux, x86_64, debian-gcc
OK
- Version checked
- 0.4.0
- Time taken
- 412 s
r-devel-linux-x86_64-fedora-clangThe unreleased R on Linux, x86_64, fedora-clang
OK
- Version checked
- 0.4.0
- Time taken
- 418 s
r-devel-linux-x86_64-fedora-gccThe unreleased R on Linux, x86_64, fedora-gcc
OK
- Version checked
- 0.4.0
- Time taken
- 410 s
r-devel-windows-x86_64The unreleased R on Windows, x86_64
OK
- Version checked
- 0.4.0
- Time taken
- 704 s
r-oldrel-macos-arm64The previous release of R on macOS, arm64
OK
- Version checked
- 0.4.0
- Time taken
- 157 s
r-oldrel-macos-x86_64The previous release of R on macOS, x86_64
OK
- Version checked
- 0.4.0
- Time taken
- 811 s
r-oldrel-windows-x86_64The previous release of R on Windows, x86_64
OK
- Version checked
- 0.4.0
- Time taken
- 941 s
r-patched-linux-x86_64The patched release of R on Linux, x86_64
OK
- Version checked
- 0.4.0
- Time taken
- 621 s
r-release-linux-x86_64The current release of R on Linux, x86_64
OK
- Version checked
- 0.4.0
- Time taken
- 616 s
r-release-macos-arm64The current release of R on macOS, arm64
OK
- Version checked
- 0.4.0
- Time taken
- 114 s
r-release-macos-x86_64The current release of R on macOS, x86_64
OK
- Version checked
- 0.4.0
- Time taken
- 780 s
r-release-windows-x86_64The current release of R on Windows, x86_64
OK
- Version checked
- 0.4.0
- Time taken
- 756 s
- 13 OK
Over time
No change since 25 Oct 2026
As a list (8)
| Changed | Worst status | OK | Notes | Warnings | Errors |
|---|---|---|---|---|---|
| 25 Oct 2026 | OK | 13 | 0 | 0 | 0 |
| 24 Oct 2026 | Error | 12 | 0 | 0 | 1 |
| 5 Aug 2026 | OK | 13 | 0 | 0 | 0 |
| 1 Aug 2026 | Note | 12 | 1 | 0 | 0 |
| 9 Jun 2026 | OK | 13 | 0 | 0 | 0 |
| 8 Jun 2026 | Error | 12 | 0 | 0 | 1 |
| 25 Apr 2026 | OK | 12 | 0 | 0 | 0 |
| 24 Mar 2026 | Note | 4 | 1 | 0 | 0 |
Since March 2026
Downloads
Method, Downloads Method Download figures count requests logged by each distribution channel. They are not counts of installs or of users, because each channel publishes its own totals and this site reads them.Downloads
- Total downloads in the last 30 days
- 398+19.5% up on the 30 days before, the better directionIt is the sum of 3 channels: CRAN, r2u and autoCRAN.
CRAN rank
8,576 of 26,530
CRAN
396 downloads in the last 30 days
- Rank
- 8,576 of 26,530
- Change
- +23.8% up on the 30 days before, the better direction
It is in the total. Take it out
r2u
1 downloads in the last 30 days
- Rank
- 19,986 of 30,526
- Change
- −75% down on the 30 days before, the worse direction
It is in the total. Take it out
autoCRAN
1 downloads in the last 30 days
- Rank
- 25,688 of 29,212
- Change
- −88.9% down on the 30 days before, the worse direction
It is in the total. Take it out
The total is 398 downloads in the last 30 days. It is the sum of 3 channels: CRAN, r2u and autoCRAN.
Over time
Dependencies
- Needs
- 23
- Dependent packages
- 0
- Suggested by
- 0
Needs (23)
- data.table
- doFuture
- dplyr
- foreach
- future
- future.apply
- future.callr
- ggplot2
- glmnet
- grf
- gt
- Matrix
- mvtnorm
- parallel
- patchwork
- policytree
- progressr
- randomForest
- rlang
- stats
- survival
- utils
- weightedsurv
- Installing it adds
- 89 packages, 82.4 MB of source
- Of those, need compilation
- 43
Code
Method, Code Method Code metrics come from reading the released source of each package version. The package is never installed, loaded or run.Code metrics
README, vignettes, a NEWS file and the shares read from its help pages. Files kept only in the repository, such as a pkgdown configuration or CI files, are read by the repository scan instead.
- Functions
- 705
- Public exports
- 226
- Lines of R code
- 77,234
- Median complexity
- 5
Functions (705)
Size and composition
Lines by kind (118,185)
| Kind | Lines | Share |
|---|---|---|
| R code | 77,234 | 65% |
| Tests | 12,265 | 10% |
| Documentation | 27,531 | 23% |
| Guides | 1,155 | 1.0% |
Lines by language
| Language | Lines | Share |
|---|---|---|
| R | 89,499 | 76% |
| Rd | 27,531 | 23% |
| Vignettes | 1,155 | 1% |
Languages are counted from file extensions.
- Files
- 618
- R functions
- 705
- Object systems
- S3: 60 methods
- Deprecated functions
- 3
Complexity
- Median
- 5
- Mean
- 10.63
- Highest
- 303
- Median lines per function
- 30
About complexity
Cyclomatic complexity counts the independent paths through a function: 1 is a straight line, higher is harder to test. R functions only.
Call graph figures
- R functions
- 705
- Calls
- 761
- Unconnected
- 130
- Groups
- 28
Growth (2 releases)
Release changes
Tests
Coverage was measured, but at least one test failed during the run.
- Lines run by tests
- 38.1%
- Expressions run by tests
- 38.7%
- Test cases
- 485
- Exports named in tests
- 31.4%
Coverage by file (111)
Coverage run
- Lines counted
- 33,573
- Lines the tests ran
- 12,793
- Tests passed
- No
- Measured with
- covr 3.6.5 on R 4.6.1
Test suite
- Has tests
- Yes
- Test frameworks
- testthat, tinytest
- Test cases
- 485
- Lines of tests
- 12,265
- Test lines per line of code
- 0.16
Documentation
- Exports documented
- 100%
- Arguments documented
- 95.8%
- Return value documented
- 100%
- Help pages with examples
- 48.5%
- Examples run in checks
- 21.3%
Guides (2)
Other documentation
- README
- Yes, 814 words
- Release notes file
- Yes
- Help pages
- 427
- Lines of documentation
- 27,531
People
Method, People Method People on the site are the names packages give them in their Author and maintainer identity
DESCRIPTION files: authors from the author list, and the maintainer from the Maintainer field. Spellings of one name become one person only where the rules below allow it, and when in doubt the rules keep people apart.
Maintainer since 0.1.0 (2026), author
Repository
Method, figures by host Method Repository signals are the figures read from the source repository a package links to: stars, forks, issues, commits, releases and the time issues take to close. They are read from GitHub, GitLab, Codeberg and Bitbucket.Repository signals
URL and BugReports fields of its DESCRIPTION file. Read-only mirrors, the cran and bioc accounts on GitHub and git.bioconductor.org, are left out.
larry-leon / forestsearch on github.com
- Stars
- 3+50% up on 30 days ago, the better direction
- Forks
- 2
- Open issues
- 0
- Last commit
- 28 Oct 2026
Activity
- Commits
- 2,713
- Open pull requests
- 0
- Tagged releases
- 1
- Latest tagged release
- v0.4.0, 10 Oct 2026
- In development
- Default branch at 0.4.0.9000, ahead of CRAN 0.4.0 (checked 2026-10-25)
- Issues closed in
- –
- Pull requests closed in
- 0 days (median)
- Pull requests merged
- 67%
- Created
- 7 Oct 2025
- Licence file reads as
- –
Development practices (6)
| Kind | Found |
|---|---|
| Continuous integration | GitHub Actions |
| Docs source | pkgdown GitHub Pages site last deployed 2026-10-19 The repository has a site deploy workflow pkgdown site last built 2026-10-19 |
| CRAN release process | cran-comments.md |
| Lint, format, editor | RStudio project |
Method, repository practices Method Beta Each week a scan of the public source repository a package links to looks for the tools a maintainer has set up, and the Repository section lists the findings. Repositories on GitHub and GitLab are scanned.Repository practices
R CMD build reads .Rbuildignore and leaves out files used only in development, such as .github/, .lintr, renv/, a Dockerfile and cran-comments.md, so the released source file holds almost none of them. The repository is the one place these files stay visible.
AI tools
Method, AI tools Method Beta What is found in a repository is not a measure of the code.AI tool findings
Tools
| Tool | First seen | Found | Commits crediting it |
|---|---|---|---|
| Claude Code | 15 Jul 2026 | Seen in the repository.claudeCLAUDE.mdNamed in .RbuildignoreCLAUDE.mdPull request it wrote: opened by a project member | 975 at least |
- Seen in the repository
- Named in .Rbuildignore
- Pull request
Models
| Model | Context window | Commits | First commit | Last commit | Credit lines of |
|---|---|---|---|---|---|
| Claude Opus 5 | 1M | 5 at least | 29 Jul 2026 | 30 Jul 2026 | Claude Code |
| Claude Opus 5 | 54 at least | 29 Jul 2026 | 6 Aug 2026 | Claude Code | |
| Claude Fable 5 | 12 at least | 21 Jul 2026 | 21 Jul 2026 | Claude Code | |
| Claude Opus 4.8 | 23 at least | 18 Jul 2026 | 21 Jul 2026 | Claude Code | |
| Claude Opus 4.8 | 1M | 9 at least | 15 Jul 2026 | 23 Jul 2026 | Claude Code |
History
Method, History Method Archived is built from CRAN's archive records, its list of check deadlines and Bioconductor's package records. Every figure is counted to 28 Oct 2026, the day the data was read.Packages leaving
- On CRAN
- Release
Release notes (0.4.0)
Changes since the last CRAN release (0.1.0)
Breaking changes
showten_subgroupsis removed fromforestsearch()andsubgroup.consistency(). Neither function has..., so a call that passes it now fails with "unused argument". Useshow_candidate_summaryinstead.- Changed defaults in
forestsearch()(old -> new): use_lasso:TRUE->FALSEuse_grf:TRUE->FALSEdmin.grf:12->0frac.tau:0.6->0.8d0.min:12->10d1.min:12->10max_subgroups_search:10->Infvi.grf.min:-0.2->NULLstop_threshold:0.95->pconsistency.thresholdparallel_args:list(plan = "callr", workers = 6, show_message = TRUE)->list(plan = "multisession", workers = .default_parallel_workers(), show_message = TRUE)- Changed default in
subgroup.consistency():stop_Kgroups:10->200. - Changed default in
forestsearch_Kfold():Kfolds:nrow(fs.est$df.est)->.fs_cv_nobs(fs.est). - Changed default in
cox_ahr_cde_analysis():output_dir:tempdir()->"plots"(files are written only whensave_plots = TRUE). save_leff_calibration()now requiresoutput_dir. Called without it, the function stops instead of writing to"_data"in the working directory; passoutput_dir = "_data"to keep the former behaviour.
New features
- GLM outcomes: binary (odds ratio), continuous (mean difference) and count/rate (incidence rate ratio) endpoints, selected with the
outcome_typeandeffect_measurearguments offorestsearch(). - DINA and GRF as subgroup identifiers alongside the consistency search, selected with
forestsearch(subgroup_method = c("consistency", "dina", "grf")); seedina_subgroup()and, for GLM outcomes,grf.subg.harm.glm(). - Post-selection inference: multiplier resampling (
fs_mr_inference()), with infinitesimal-jackknife (IJ) standard errors and field bounds. - Operating-characteristics functions:
fs_oc_family_enumerate(),fs_oc_predict(),fs_oc_grid()andfs_oc_invert(). - Threshold rules on the forest-search consistency path (survival HR and binary OR only): when only
c1is given,c2 = 0.8 * c1on the ratio scale;c2 > c1is an error. - Calibrated declaration threshold:
fs_declaration_calibration(). forestsearch()gainspconsistency.digits(default 2): the consistency proportion is rounded to this many digits before it is compared withpconsistency.threshold.- grf forest training is capped at 2 threads when
_R_CHECK_LIMIT_CORES_is set (as underR CMD check --as-cran); otherwise grf's own default applies unchanged. - Printed post-selection output and documentation simplified; methodology reference León and Anderson (2026) <doi:10.48550/arXiv.2609.38361>.
Development changes after 0.3.5 (not released on CRAN)
- MR's admission set now uses the screen's rounded consistency threshold (forest search only). The search admits on
round(Pcons, pconsistency.digits) >= p*, but MR's consistency floor was built from the exact cutoffqnorm((1 + p*) / 2), so MR re-selected under a different admission rule from the one that produced the selected subgroup, in the under-adjusting direction. The floor is now built from the effective threshold.fs_pcons_eff(p*, digits)on both consistency paths.fs_mr_inference()gainspconsistency.digits(defaultNULL, thesubgroup.consistency()default);forestsearch()passes its own value. Corrected estimates, field bounds and the Bonferroni pair can move for forest search. On the GBSG application (seed 8316951) the corrected HR moves from 1.2806 to 1.2762, the field lower bound from 0.6365 to 0.6336, and the Bonferroni pair from 0.5099 / 0.8397 to 0.5087 / 0.8396. GRF and DINA carry no consistency screen and are unaffected (identical output). - `fs_declaration_calibration()`: FW-hat and the implied p-star are now computed at the screen's rounded admission rule. The screen admits on
round(Pcons, pconsistency.digits) >= p*, which isPcons >= 0.895forp* = 0.90at 2 digits, butfw_sizewas taken at the exactqnorm((1 + p*) / 2). It is now taken at the effective thresholdqnorm((1 + pcons_eff) / 2)(returned aspcons_effandz_pstar), withdigitsread from the fit'sargs_call_all(default 2, source recorded), so `fw_size` values rise relative to previous releases and now depend onpconsistency.digits;admitted_pstaruses the same threshold. On the GBSG application (c0 = 0.75,alpha = 0.10)fw_size(c0)moves from 0.6508 to 0.6672. `kappa_hat` is unchanged. The c0 table'spstar_impliedcolumn is replaced by what to set to runkappa_hatas a p-star screen:pstar_settable(smallest settable p* at the fit's digits whose rounded screen is at or abovekappa_hat;pstar_achievable = FALSEwhen none is),pcons_eff_settable,z_eff_settable,z_gap, anddigits_fine/pstar_fine/z_gap_fine(smallest digits with a gap under 0.01 in z). Underconsistency_method = "split"the screen is not a threshold onT, sofw_size,admitted_pstarand the settable columns areNA/NULL. - The
fs_dgm_feasibility()example now runs (it calledgenerate_glm_dgm()without its required data arguments);fs_plot_bias_coverage()captions use\uescapes, so the R source is ASCII -- the rendered text is unchanged. - `forestsearch()` gains `pconsistency.digits` (default 2). It was previously reachable only on the internal consistency functions (
subgroup.consistency(),evaluate_subgroup_consistency(),evaluate_consistency_twostage()); everyforestsearch()run was pinned to 2 digits. The consistency proportion is rounded to this many digits *before* it is compared withpconsistency.threshold, so the setting governs admission, not only display; the roxygen for all four functions now says so. Default behaviour is unchanged: at 2 the GBSG application's consistency table is identical to the previous package's.fs_family_report()lists the argument in its consistency-screen row. - New `fs_dgm_feasibility()`: a design-time check that the planted region can be declared at all. Given a
glm_dgm-- the interfacefs_oc_predict()andfs_oc_grid()accept -- it drawsn_repreplicates per sample size through the DGM's *own* generator (simulate_from_glm_dgm(), the function the campaign templates call, never a re-implementation) and reports, pern: the share of replicates on which the planted region is undeclarable (size<=n.min, the strict testsubgroup.search()itself applies), the share under the per-arm events floor, the share on which the estimand does not exist under the estimability boundary's per-estimand condition, and size and per-arm cell summaries.$feasibleisTRUEwhen every undeclarable share is at or belowtolerance(default 0.05). The print method is loud and unconditional. On the ACTG175 OR 0.75 design this returnsFALSEat n = 500 and n = 750: the planted region is at or belown.min = 60in 90% of replicates at n = 500, so what the search declares there is a larger overlapping region, not the planted one. It imposes nothing -- the floors are read and reported, never applied, andforestsearch()never consults it. The function does not change the RNG kind and restores the caller's RNG stream on exit; the caller's matching obligation, stated in the roxygen, is to build and calibrate the DGM *before* any replicate switches the kind, since calibrating afterwards yields a different super-population. Survival DGMs are not accepted, and the error and?fs_dgm_feasibilitysay exactly what supporting them would need rather than guessing:setup_gbsg_dgm()objects carry a different generator (simulate_from_dgm()) whoseanalysis_timeandcens_adjustarguments have no GLM counterpart and change the per-arm event counts. - The estimator boundary now returns `NA` with a reason where the estimand does not exist, instead of a finite divergent number.
glm()andcoxph()do not fail on a slice with an empty cell or a zero-event arm: they return a large finite coefficient withconverged = TRUE, which was then admitted as an estimate (a zero-cell OR returned 19.97 with SE 4809). The existence condition is now checked before the fit, per estimand: OR requires all four cells (control/treated x events/non-events)>= 1; RR, IRR and HR require at least one event in each arm. A candidate failing it returnsestimate = NA,se = NA,converged = FALSEand areasonnaming the empty cell, and takes the existing fit-failure status (status 5) -- anNAeffect cannot rank, so no selection logic changes. For the ratio estimands only, a fit reportingconverged = FALSEis likewise non-estimable ("non-convergent fit"). Unaffected, byte-identical: RD, IRD and MD, which exist on any slice -- in particular RD's tier-3 raw-proportions fallback returnsconverged = FALSEby design and is never caught. This is not an admission floor:n.min,d0.min/d1.minand every DINA/GRF floor are unchanged, nothing is forwarded to DINA or GRF, and no minimum count is imposed anywhere. Non-estimable candidates are counted, not dropped silently:filter_counts$n_nonestimableandfilter_counts$nonestimable_reasonscarry the tally and its reasons,subgroup.search(details = TRUE)prints them, andfs_family_report()gains an "estimability boundary" stage row. Committed results are unaffected -- no declared subgroup in the committed binary record violates the four-cell condition (3,313 replicates,a3374e6f), and no committed survival bundle stores a non-finite estimate or SE (930 bundles, 568,757 declared rows). - `dina_frontier()`'s display caps now default to `Inf` and say when they trim.
max_per_covariateandmax_subgroupsdefaulted to3Land10L, which silently dropped covariates whole and truncated the round-robin rank-2 pass -- observed in the applied vignettes, where the printed frontier was not the frontier. Both now default toInf, aligning withmax_subgroups_search's ownInfdoctrine, and a user-supplied finite value that actually removes rows raises a warning naming the kept and available counts (condition classdina_frontier_cap_trim). Affected: callers who relied on the finite defaults -- they now receive the full table; every committed in-repo caller passes both caps explicitly, so no committed rendered table changes. Unaffected: the candidate pool anywhere. The frontier is a display object;dina_subgroup()never consults it, andforestsearch(use_dina = TRUE)still supplies the finite screening caps itself, so the screening pool is byte-identical. Under the defaultselected_only = TRUEthat screening frontier is discarded, so the trim warning is muffled there rather than naming a table nobody sees. - `dina_args` frontier keys now warn when they are ignored. The seven
dina_frontier()keys --scope,m_diff,n_min,direction,max_per_covariate,max_subgroups,digits-- are inert undersubgroup_method = "dina", which selects throughdina_subgroup()and never consults a frontier table. Supplying any of them there now raises a singlewarning()per fit naming every offending key at once, rather than accepting them silently. Affected: `subgroup_method = "dina"` callers who pass frontier keys -- the selection is unchanged, only the messaging. Unaffected: theuse_dinascreening path, where the keys still act (digitsunderselected_only = TRUE, all seven underselected_only = FALSE), and every othersubgroup_method. - DINA now refuses the identity-scale estimands `"RD"` and `"IRD"`. DINA scores candidates on the family link scale, so its admission floor was derived as
log(hr.threshold)for the ratio families and as the identity threshold forgaussian. For an expliciteffect_measure = "RD"that derivation was meaningless: a 7-percentage-point threshold became a log-odds floor oflog(0.07) = -2.66, which admitted nearly every candidate, silently. There is no identity-scale number DINA could correctly apply on a link scale, so the derivation now stops instead, naming the ratio and non-DINA alternatives. The guard sits at them_diffderivation itself, so both routes to it are covered:subgroup_method = "dina"(an error, raised before the DINA model is fit) anduse_dinascreening withdina_args$selected_only = TRUE(where it surfaces through that path's existing"DINA analysis failed"warning and the run continues with no DINA cuts). Affected: only calls that explicitly request `"RD"` or `"IRD"` together with DINA -- nothing committed does, and the defaults per outcome type ("OR","MD","IRR") are all outside the guard. Unaffected:family = "gaussian"with"MD", which is a correct identity-scale floor and cannot reach the refusal, and every ratio estimand on every family. - The two effect thresholds are now a pair on the forest-search consistency path. For
subgroup_method = "consistency"with survival (HR) or binaryeffect_measure = "OR"-- the estimands whosec1andc2sit on one comparable ratio scale --forestsearch()now enforcesc2 <= c1and derives ac2the caller did not supply. Affected: callers who set `c1` without `c2` (effect.thresholdorhr.thresholdalone), which used to leavec2at the package default1.0whateverc1was and now resolvesc2 = 0.80 * c1on the ratio scale -- 1.25 -> 1.00, 1.00 -> 0.80, 0.90 -> 0.72 -- announced with a message and carried into every bootstrap replicate and cross-validation fold. The default pair (1.25, 1.0) is the rule's fixed point, so a call that set neither threshold resolves exactly what it did before, and a call that passedhr.threshold = 1.25explicitly is likewise unmoved and only gains the message. Also affected: callers with `c2 > c1`, previously accepted and degenerate -- the consistency-stage entry condition re-screens the admitted family onc2, so candidates the screen let through were discarded at the stage boundary and the run could report no subgroup for a reason nothing in the output named. That configuration is now an error, raised before any model is fit, naming both values and the spellings the caller used. Supplying both spellings of one threshold at disagreeing values is an error too. An explicitly suppliedc2is never overridden, and no selection logic changed. Unaffected:subgroup_method = "dina"and"grf", which return before the consistency stage and never consultc2, and the identity-scale estimands"RD","IRD"and"MD"together with"IRR", all of which resolve exactly as before in every branch. - Bootstrap replicates and cross-validation folds now resolve the thresholds the original fit resolved.
forestsearch()resolves the screening (c1) and consistency (c2) thresholds through branches guarded by whether the caller supplied them, and for the legacy spellings (hr.threshold,hr.consistency) that was detected withmissing(). Becauseforestsearch_bootstrap_dofuture(),forestsearch_Kfold()andforestsearch_tenfold()replay the captured argument list with every formal supplied,missing()wasFALSEinside a replicate, and a replicate could resolve thresholds its parent never used. Affected: identity-scale analyses (`effect_measure` `"RD"`, `"IRD"` or `"MD"`) that left `c1` or `c2` at its default, or supplied only one of the two, and then ran the bootstrap or cross-validation -- those replicates usedc2 = 1.0where the fit used0.0, and on"MD"alsoc1 = 1.25where the fit used0.0. A per-split effect of 1.0 is a threshold no candidate can meet, so the affected folds and replicates identified nothing. Ratio measures ("OR","RR","IRR") and survival were never affected, and the fix leaves every original fit's resolution byte-identical -- only what a replay sees changes.
The notes are cut short here.