Blinded Sample Size Re-Estimation for Binary Endpoints
Overview
Tools for blinded sample size re-estimation (BSSR) in two-arm clinical trials with binary endpoints, together with the exact power and sample size calculations that the re-estimation relies on. Five exact statistical tests are implemented: Pearson chi-squared, Fisher exact, Fisher mid-p, Z-pooled exact unconditional, and Boschloo exact unconditional. Each test is available with a one-sided or a two-sided alternative, and the exact unconditional tests can be combined with the Berger-Boos procedure. Sample sizes can be re-estimated either at the planning stage, to study the operating characteristics of a design, or from the blinded data of a trial that is under way. Statistical methods based on Mehrotra et al. (2003) doi:10.1111/1541-0420.00051, Berger and Boos (1994) doi:10.1080/01621459.1994.10476836 and Kieser (2020) doi:10.1007/978-3-030-49528-2_21.
This is a major release. It corrects the p-value of the exact unconditional tests, adds
two-sided alternatives, the Berger-Boos procedure and a function for re-estimating the
sample size from observed interim data, and moves the inner loops to compiled code. The
user interface has changed in ways that are not backward compatible, which is why the
major version number has been raised.
Corrections
- The exact unconditional tests accumulated the null probabilities along an arbitrary ordering of the outcomes. Outcomes sharing the same value of the ordering statistic were therefore split, and could receive different p-values. With
N1 = N2 = 7the outcomes(x1, x2) = (5, 1)and(6, 2)both have a Fisher p-value of 2/39 and cannot be distinguished by the Boschloo test, yet the old code assigned them 0.0216 and 0.0287 and rejected at the first but not the second. Tied values are now grouped explicitly and every member of a group receives the tail probability accumulated up to the last member of that group. The rejection region no longer depends on how the sorting routine breaks ties.
Show all changes in 2.0.0Hide the rest of the changes in 2.0.0
- The Z-pooled branch indexed the matrix of binomial probabilities by the responder count rather than by the position of that count among the retained values. The two coincided in the configurations reached by the old code, so the results were correct, but the indexing broke as soon as the retained counts were not contiguous.
- The Boschloo branch discarded outcomes whose Fisher p-value was not below the smallest Fisher p-value among outcomes with a non-positive risk difference. The truncation was sound but had no natural counterpart for a two-sided alternative, and it has been removed. The whole outcome grid is now scanned, which the move to compiled code makes affordable.
pmin(1, x)with a scalar first argument drops thedimattribute ofx. This affected the matrix of p-values returned for a two-sided chi-squared test.- The allocation ratio was not preserved by the re-estimation when
rwas not 1. The interim size of group 1 wasceiling(omega N1)and the second-stage size wasceiling(r N22), so the final size of group 1 was rounded up three separate times and did not equalceiling(r)times the final size of group 2. Withr = 2,N2 = 33andomega = 0.8the interim allocation was 53 to 27 rather than 54 to 27, and a re-estimated control group of 40 gave 79 rather than 80 in group 1. Both the interim and the final size of group 1 are now obtained from the size of group 2 by a singleceiling(r ...), and the second stage follows as the difference. The allocation ratio is therefore exact wheneverris a whole number, and as close as whole numbers allow otherwise. Results forr = 1are unchanged.BinaryBSSR()brings group 1 toceiling(r N2.final)for the same reason, which also corrects an imbalance that is already present in the observed interim data.
New features
- All five tests accept
alternative = 'greater'(the default, and the behaviour of version 1) oralternative = 'two.sided'. For the conditional tests the two-sided p-value follows the convention selected bytsmethod, either'minlike', which matchesstats::fisher.test, or'central'. The chi-squared and Z-pooled tests order outcomes by the absolute value of the Z statistic when the alternative is two-sided. - The number of grid points used to search over the nuisance parameter of the unconditional tests is now the argument
n.grid, which defaults to 100 and reproduces the grid of version 1. A finer grid gives larger p-values and a more accurate test. - The Berger-Boos procedure is available through the argument
bb.gamma. A positive value restricts the search over the nuisance parameter to an exact Clopper-Pearson confidence interval computed from the observed number of responders, and addsbb.gammato the resulting p-value. The default of 0 disables the procedure. BinaryBSSR()re-estimates the sample size from the blinded data of a trial that is under way. It takes the interim sample size of each group and the pooled number of responders, and returns the number of patients still to enrol in each group. This complementsBinaryPowerBSSR(), which evaluates a re-estimation rule at the planning stage.- Every function returns a classed object with a
print()method, andBinaryRR(),BinaryPower(),BinarySampleSize()andBinaryPowerBSSR()also have aplot()method. The classes arebbssr_rr,bbssr_power,bbssr_samplesize,bbssr_powerbssrandbbssr_bssr. - The
plot()methods acceptmain,sub,xlab,ylab,base_sizeandcolours, so the title, the axis labels, the font size and the palette can be replaced without editing the returned object. A label left atNULLkeeps the text built from the object and a label set toNAis dropped. Where a legend is drawn,legend.titleandlegend.labelsrename it, and where a vertical scale is continuous,ylimsets its range throughcoord_cartesian(), which hides rather than removes the points outside the range. The reference lines are no longer fixed:plot.bbssr_powerbssr()andplot.bbssr_samplesize()takeref.line, andplot.bbssr_samplesize()also takesref.line.N2. The methods that draw a curve also takeshow.points, which removes the marker at each evaluated point and leaves the curve alone, so a fine grid stays legible. This matters whenDelta.Tis 0, since the two power columns ofBinaryPowerBSSR()are then rejection probabilities under the null hypothesis and the line belongs at the level of significance rather than at the target power. The defaults reproduce the earlier plots exactly. BinaryPowerBSSR()reports the expected total sample size in a new columnE.N, and carries the interim sample sizes as the attributesn1.interimandn2.interim.- Arguments are validated, and invalid sample sizes, significance levels, allocation ratios and grid sizes now produce an informative error.
Performance
- The maximization over the nuisance parameter and the summation of the binomial mass over the rejection region are implemented in C++ through
Rcpp. BinaryPowerBSSR()evaluatesBinarySampleSize()once per distinct pair of recovered response probabilities andBinaryRR()once per distinct pair of final sample sizes, rather than once per interim outcome.
Interface changes that are not backward compatible
- The
weightedargument ofBinaryPowerBSSR()has been removed, along with the weighted design it selected. Calls that supply it will fail with an unused argument error. - The
asmd.p1andasmd.p2arguments ofBinaryPowerBSSR()have been removed. They entered the calculation only through the weights of the weighted design, so with that design gone they had no effect on the result. The planning assumption is carried byDelta.Atogether with the initial sample sizesN1andN2. Calls that supply them will fail with an unused argument error. BinaryPower()returns a one-row-per-scenario data frame of classbbssr_powerrather than a bare numeric vector. Code that used the returned value directly should now read thePowercolumn.BinaryRR()returns a logical matrix carrying the classbbssr_rrand the design settings as attributes. The matrix itself is unchanged, so indexing andsum()behave as before, but printing now goes throughprint.bbssr_rr().BinarySampleSize()andBinaryPowerBSSR()gained columns in their output, andBinarySampleSize()returns integer rather than double sample sizes.restrictednow defaults toFALSEinBinaryPowerBSSR()instead of having no default.ggplot2andRcpphave moved intoImports, so a compiler is required to install the package from source.
Documentation
- The vignettes have been rewritten and a fourth has been added.
bbssr-introductioncovers the whole package,bbssr-statistical-methodsderives the tests and the re-estimation rules,bbssr-interim-reestimationfollows a single trial from planning to the interim decision, andbbssr-validationcompares the package againststats,Exactandexact2x2and reports timings. - The test suite has been rewritten around reference implementations that follow the definitions of the tests directly, so the p-values are checked against a direct evaluation rather than against stored values.
From NEWS.md in the release
Install
Health
- OK13 OK2026-09-08
- ERROR12 OK, 1 ERROR2026-09-07
- OK13 OK2026-08-05
- NOTE12 OK, 1 NOTE2026-08-01
- OK14 OK2026-03-10
Documentation
- Help pages
- 15 (1 internal)includes a package overview page
- Examples that run
- 86%12 run in a plain check · 2 only when donttest examples are enabled (R CMD check --as-cran)
- Exported functions with examples
- 100%
- Documented parameters
- 100%
- Return-value docs
- 100%
- Help pages citing references
- 0%
Downloads
Repository
Stars over time
Commits over time
10 development-tooling and community-health practices detected across 5 families in the upstream repository
Checks run against github.com/gosukehommaex/bbssr on 2026-10-18.
The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel
GitHub Pages site last deployed 2026-10-08 · The repository has a site deploy workflow
Show all practicesHide 1 practice
Dependencies
Code & Tests
People & History
Pick two releases to compare their code metrics.
- RR 4.6.0 released · 2026-04-24
- 2.0.0Latest
- 1.0.22025-06-18
- RR 4.5.0 released · 2025-04-11
Package metadata
- First published
- 2025-06-18
- Total releases
- 2 / 1 yrs
- License
- MIT + file LICENSE OSI
- Minimum R
- ≥ 3.5.0
- Download size
- 635 KB
Cite
Cite this package
Run in R for the authors' preferred citation:
citation("bbssr")This package has no citation file, so citation() returns this entry built from DESCRIPTION.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-21, which the citation names so these numbers can be found later. More on citing and the projects behind them.