Computing Confidence Interval Functions with cifunction
A Stata Package for Visualizing Statistical Uncertainty
The cifunction package for Stata computes and graphically displays all possible confidence intervals around a point estimate, creating what’s known as a confidence interval function, confidence curve, p-value function, or consonance interval. This approach conveys more information than traditional single-level confidence intervals by showing the full range of values compatible with the data at all confidence levels.
confidence interval function, confidence curve, p-value function, consonance interval, Sullivan and Foster, Stata statistical software, statistical visualization, uncertainty quantification
1 Overview
Traditional confidence intervals present a single level of uncertainty (typically 95%), but this dichotomous approach discards valuable information about the data. The confidence interval function (CI-function) provides a more complete picture by displaying all possible confidence intervals simultaneously.
2 Installation
Install cifunction from SSC (Statistical Software Components):
3 Syntax
{stata, echo=TRUE, collectcode=TRUE, statapath="/Applications/StataNow/StataMP.app/Contents/MacOS/StataMP"}cifunction #b, se(#) [options]
3.1 Required Arguments
| Argument | Description |
|---|---|
#b |
Point estimate (coefficient or exponentiated value like OR, HR, IRR) |
se(#) |
Standard error of the estimate |
3.2 Optional Arguments
| Option | Description |
|---|---|
df(#) |
Degrees of freedom (for t-distributed estimates) |
eform |
Indicates coefficient is exponentiated (OR, RR, IRR) |
figure[(options)] |
Produces CI-function plot with optional twoway options |
saving(filename, replace) |
Saves results to file |
4 Understanding CI-Functions
A CI-function graphically represents the relationship between confidence levels and confidence intervals:
- Peak of curve: Indicates the point estimate
- Concentration around peak: Reflects precision of estimate
- Narrow curve: High precision (large sample size)
- Broad curve: Low precision (small sample size)
4.1 Advantages Over Single-Level CIs
- Complete information: Shows compatibility of all values with data
- Precision visualization: Curve width directly shows estimate precision
- Multiple comparisons: Reveals whether data provide reassurance about null effects
- Nuanced interpretation: Moves beyond binary “significant/non-significant” thinking
Values toward the peak are more compatible with the observed data (assuming the statistical model is correct). The curve explicitly shows the gradual nature of statistical evidence rather than suggesting arbitrary cutoffs.
5 Practical Examples
5.1 Example 1: Basic Risk Ratio
Reproducing Figure 1 from Sullivan and Foster (1990):
* Get standard error for RR=2.0 with p=0.05
getregstats 2.0, p(0.05) mod(rr)
* Create CI-function with log-scaled x-axis
cifunction 2.0, se(.707306) eform ///
fig(xscale(log) xlab(0.5 1 2 5 10) ///
xtitle("Risk Ratio (Log Scale)"))
## file ()print() not found
## r(601);
##
##
##
##
## ------------------------------------------------------------------------------
## | Risk Ratio Std. Err. z P>|z| [95% Conf. Interval]
## -------------+----------------------------------------------------------------
## Estimates | 2 .707306 -1.96 0.050 1 4
## ------------------------------------------------------------------------------5.2 Example 2: Age-Stratified Rate Ratios
Using Doll-Hill smoking data, stratified by age group:
* Load data and fit models
webuse dollhill3, clear
* Fit Poisson models for each age category
forvalues i = 1/4 {
poisson deaths smokes if agecat==`i', exposure(pyears) irr
}
* Plot all four age-stratified CI-functions
cifunction 5.736638 2.138812 1.46824 1.35606, ///
se(4.181258 .6520701 .295728 .2748845) eform ///
fig(xscale(log) xlabel(.3 .5 1 2 5 10 20 50 100) ///
legend(label(1 "35-44") label(2 "45-54") ///
label(3 "55-64") label(4 "65-74") ///
title("Age Group", size(small))) ///
xtitle("Rate Ratio (Log Scale)"))
## file ()print() not found
## r(601);
##
##
## (Doll and Hill (1966))
##
##
## Iteration 0: Log likelihood = -4.0705386
## Iteration 1: Log likelihood = -3.9613823
## Iteration 2: Log likelihood = -3.9612634
## Iteration 3: Log likelihood = -3.9612634
##
## Poisson regression Number of obs = 2
## LR chi2(1) = 9.73
## Prob > chi2 = 0.0018
## Log likelihood = -3.9612634 Pseudo R2 = 0.5511
##
## ------------------------------------------------------------------------------
## deaths | IRR Std. err. z P>|z| [95% conf. interval]
## -------------+----------------------------------------------------------------
## smokes | 5.736638 4.181258 2.40 0.017 1.374811 23.93712
## _cons | .0001064 .0000753 -12.94 0.000 .0000266 .0004256
## ln(pyears) | 1 (exposure)
## ------------------------------------------------------------------------------
## Note: _cons estimates baseline incidence rate.
##
## Iteration 0: Log likelihood = -5.4793565
## Iteration 1: Log likelihood = -5.4104407
## Iteration 2: Log likelihood = -5.41027
## Iteration 3: Log likelihood = -5.41027
##
## Poisson regression Number of obs = 2
## LR chi2(1) = 7.59
## Prob > chi2 = 0.0059
## Log likelihood = -5.41027 Pseudo R2 = 0.4123
##
## ------------------------------------------------------------------------------
## deaths | IRR Std. err. z P>|z| [95% conf. interval]
## -------------+----------------------------------------------------------------
## smokes | 2.138812 .6520701 2.49 0.013 1.176691 3.887609
## _cons | .0011243 .0003246 -23.52 0.000 .0006385 .0019798
## ln(pyears) | 1 (exposure)
## ------------------------------------------------------------------------------
## Note: _cons estimates baseline incidence rate.
##
## Iteration 0: Log likelihood = -6.2456963
## Iteration 1: Log likelihood = -6.1713863
## Iteration 2: Log likelihood = -6.171298
## Iteration 3: Log likelihood = -6.171298
##
## Poisson regression Number of obs = 2
## LR chi2(1) = 4.01
## Prob > chi2 = 0.0453
## Log likelihood = -6.171298 Pseudo R2 = 0.2450
##
## ------------------------------------------------------------------------------
## deaths | IRR Std. err. z P>|z| [95% conf. interval]
## -------------+----------------------------------------------------------------
## smokes | 1.46824 .295728 1.91 0.057 .9893522 2.17893
## _cons | .0049037 .0009267 -28.14 0.000 .0033858 .0071021
## ln(pyears) | 1 (exposure)
## ------------------------------------------------------------------------------
## Note: _cons estimates baseline incidence rate.
##
## Iteration 0: Log likelihood = -6.1640322
## Iteration 1: Log likelihood = -6.1203079
## Iteration 2: Log likelihood = -6.1202768
## Iteration 3: Log likelihood = -6.1202768
##
## Poisson regression Number of obs = 2
## LR chi2(1) = 2.43
## Prob > chi2 = 0.1189
## Log likelihood = -6.1202768 Pseudo R2 = 0.1658
##
## ------------------------------------------------------------------------------
## deaths | IRR Std. err. z P>|z| [95% conf. interval]
## -------------+----------------------------------------------------------------
## smokes | 1.35606 .2748845 1.50 0.133 .9114509 2.017551
## _cons | .0108317 .002047 -23.95 0.000 .0074789 .0156877
## ln(pyears) | 1 (exposure)
## ------------------------------------------------------------------------------
## Note: _cons estimates baseline incidence rate.This example demonstrates how CI-functions can reveal patterns across subgroups—in this case, showing how the smoking-mortality relationship varies by age.
5.3 Example 3: Crude vs Adjusted Estimates
Comparing crude and pooled odds ratios from Mann et al. (1976):
* Case-control analysis
cci 10 36 5 40, woolf
cci 18 78 7 86, woolf
* Get standard errors
getregstats 2.835165, ucl(7.151794) mod(or)
getregstats 2.222222, ucl(7.118025) mod(or)
* Compare crude vs pooled estimates
cifunction 2.222222 2.835165, se(1.319891 1.33843) eform ///
fig(xscale(log) xlabel(.2 .5 1 2 5 10 20) ///
legend(label(1 Crude) label(2 Pooled)) ///
xtitle("Odds Ratio (Log Scale)"))
## file ()print() not found
## r(601);
##
##
##
## Proportion
## | Exposed Unexposed | Total exposed
## -----------------+------------------------+------------------------
## Cases | 10 36 | 46 0.2174
## Controls | 5 40 | 45 0.1111
## -----------------+------------------------+------------------------
## Total | 15 76 | 91 0.1648
## | |
## | Point estimate | [95% conf. interval]
## |------------------------+------------------------
## Odds ratio | 2.222222 | .69377 7.118025 (Woolf)
## Attr. frac. ex. | .55 | -.4414 .8595116 (Woolf)
## Attr. frac. pop | .1195652 |
## +-------------------------------------------------
## chi2(1) = 1.87 Pr>chi2 = 0.1719
##
##
## Proportion
## | Exposed Unexposed | Total exposed
## -----------------+------------------------+------------------------
## Cases | 18 78 | 96 0.1875
## Controls | 7 86 | 93 0.0753
## -----------------+------------------------+------------------------
## Total | 25 164 | 189 0.1323
## | |
## | Point estimate | [95% conf. interval]
## |------------------------+------------------------
## Odds ratio | 2.835165 | 1.123936 7.151794 (Woolf)
## Attr. frac. ex. | .6472868 | .1102698 .8601749 (Woolf)
## Attr. frac. pop | .1213663 |
## +-------------------------------------------------
## chi2(1) = 5.18 Pr>chi2 = 0.0228
##
##
##
## ------------------------------------------------------------------------------
## | Odds Ratio Std. Err. z P>|z| [95% Conf. Interval]
## -------------+----------------------------------------------------------------
## Estimates | 2.835165 1.338429 2.21 0.027 1.123936 7.151794
## ------------------------------------------------------------------------------
##
##
##
## ------------------------------------------------------------------------------
## | Odds Ratio Std. Err. z P>|z| [95% Conf. Interval]
## -------------+----------------------------------------------------------------
## Estimates | 2.222222 1.319891 1.34 0.179 .6937698 7.118025
## ------------------------------------------------------------------------------5.4 Example 4: Multi-Study Comparison
Comparing results across four geographic regions (Gufferman et al. 1984):
* Get standard errors from confidence limits
getregstats 0.7, l(.2) mod(rr)
getregstats 1.2, l(.8) mod(rr)
getregstats 1.3, l(.5) mod(rr)
getregstats 3.6, l(1.3) mod(rr)
* Plot all studies
cifunction .7 1.2 1.3 3.6, ///
se(.4474236 .2482485 .6337692 1.870876) eform ///
fig(xscale(log) xlabel(.05 .1 .2 .5 1 2 5 10 30) ///
legend(label(1 "Finland") label(2 "NO/LA") ///
label(3 "Denmark") label(4 "Upstate NY")) ///
xtitle("Relative Risk (Log Scale)"))
## file ()print() not found
## r(601);
##
##
##
##
## ------------------------------------------------------------------------------
## | Risk Ratio Std. Err. z P>|z| [95% Conf. Interval]
## -------------+----------------------------------------------------------------
## Estimates | .7 .4474236 -0.56 0.577 .2 2.45
## ------------------------------------------------------------------------------
##
##
##
## ------------------------------------------------------------------------------
## | Risk Ratio Std. Err. z P>|z| [95% Conf. Interval]
## -------------+----------------------------------------------------------------
## Estimates | 1.2 .2482485 0.88 0.378 .8 1.8
## ------------------------------------------------------------------------------
##
##
##
## ------------------------------------------------------------------------------
## | Risk Ratio Std. Err. z P>|z| [95% Conf. Interval]
## -------------+----------------------------------------------------------------
## Estimates | 1.3 .6337692 0.54 0.590 .5 3.38
## ------------------------------------------------------------------------------
##
##
##
## ------------------------------------------------------------------------------
## | Risk Ratio Std. Err. z P>|z| [95% Conf. Interval]
## -------------+----------------------------------------------------------------
## Estimates | 3.6 1.870876 2.46 0.014 1.3 9.969231
## ------------------------------------------------------------------------------This visualization makes it immediately apparent which studies had greater precision and how their point estimates compare.
5.5 Example 5: Meta-Analysis Context
From Rothman et al. (2008), Figure 10.5:
* Get standard errors
getregstats 0.87, l(0.70) model(or)
* Compare individual study vs meta-analysis
cifunction 0.87 0.88, se(.0965065 .0658232) eform ///
fig(xlab(.5(.1)1.3) xtitle("Odds Ratio") ///
legend(label(1 "Eisenberger et al (1998)") ///
label(2 "Summary of 10 studies") ///
ring(0) position(11))) ///
sav(figdata, replace)
## file ()print() not found
## r(601);
##
##
##
##
## ------------------------------------------------------------------------------
## | Odds Ratio Std. Err. z P>|z| [95% Conf. Interval]
## -------------+----------------------------------------------------------------
## Estimates | .87 .0965065 -1.26 0.209 .7 1.081286
## ------------------------------------------------------------------------------6 Output Variables
When using saving(), cifunction stores these variables:
| Variable | Description |
|---|---|
cilev |
Confidence levels (0 to 99.99) |
plev |
P-values (0.0001 to 1.0) |
sval |
S-values (Shannon information, see6) |
lcl# |
Lower confidence limits for estimate # |
ucl# |
Upper confidence limits for estimate # |
S-values represent the information content against a null hypothesis, measured in bits. An S-value of 4.32 corresponds to p=0.05 (roughly 4.3 bits of information against the null). See6 for details.
7 Best Practices
- Always use log scale for ratio measures (OR, RR, HR, IRR)
- Label curves clearly when plotting multiple estimates
- Save output data for further analysis or custom plotting
- Consider degrees of freedom when using regression-based estimates
- Interpret curves holistically rather than focusing on single cutoffs
8 Theoretical Foundation
CI-functions rest on the principle that statistical evidence is continuous rather than dichotomous. As2 argues:
“The P-value function provides a convenient way to present the information in the data concerning the magnitude of an effect… [It] avoids the arbitrariness of any single significance level.”
The approach aligns with modern calls for moving beyond p-value thresholds7 by presenting the full gradient of statistical evidence.
9 Comparison with Other Approaches
| Approach | Information Provided | Computational Complexity |
|---|---|---|
| Single CI | One interval at one level | Low |
| Multiple CIs | Discrete intervals | Low |
| CI-function | Continuous curve of all intervals | Low |
| Bootstrap distribution | Empirical sampling distribution | High |
| Likelihood profile | Likelihood across parameter space | Medium-High |
10 Limitations
- Assumes the statistical model is correctly specified
- Does not account for unmeasured confounding or bias
- Cannot compensate for poor study design or execution
- Interpretation requires understanding of continuous evidence
CI-functions, like all frequentist intervals, are valid only to the extent that the underlying statistical model and assumptions are appropriate for the data.
11 Citation
cifunction is free research software. Please cite it as:
Linden, A. (2019). CIFUNCTION: Stata module for computing and graphically displaying all possible confidence intervals around a point estimate. Statistical Software Components, Boston College Department of Economics.
13 See Also
getregstats(SSC): Helper for obtaining standard errorsniceloglabels(SSC): Improved logarithmic axis labelsconcurve(R package): Similar functionality in R
14 References
Abstract
R\'esum\'e Il est courant, en inf\'erence fr\'equentielle, d'utiliser un point unique (une estimation ponctuelle) ou un intervalle (intervalle de confiance) dans le but d'estimer un param\`etre d'int\'er\^t. Une question tr\`es simple se pose: peut-on \'egalement utiliser, dans le m\^eme but, et dans la m\^eme optique fr\'equentielle, \`a la facon dont les Bay\'esiens utilisent une loi a posteriori, une distribution de probabilit\'e? La r\'eponse est affirmative, et les distributions de confiance apparaissent comme un choix naturel dans ce contexte. Le concept de distribution de confiance a une longue histoire, longtemps associ\'ee, \`a tort, aux th\'eories d'inf\'erence fiducielle, ce qui a compromis son d\'eveloppement dans l'optique fr\'equentielle. Les distributions de confiance ont r\'ecemment attir\'e un regain d'int\'er\^et, et plusieurs r\'esultats ont mis en \'evidence leur potentiel consid\'erable en tant qu'outil inf\'erentiel. Cet article pr\'esente une d\'efinition moderne du concept, et examine les ses \'evolutions r\'ecentes. Il aborde les m\'ethodes d'inf\'erence, les probl\`emes d'optimalit\'e, et les applications …
Abstract
The present note explores sources of misplaced criticisms of P-values, such as conflicting definitions of “significance levels” and “P-values” in authoritative sources, and the consequent misinterpretation of P-values as error probabilities. It then discusses several properties of P-values that have been presented as fatal flaws: That P-values exhibit extreme variation across samples (and thus are “unreliable”), confound effect size with sample size, are sensitive to sample size, and depend on investigator sampling intentions. These properties are often criticized from a likelihood or Bayesian framework, yet they are exactly the properties P-values should exhibit when they are constructed and interpreted correctly within their originating framework. Other common criticisms are that P-values force users to focus on irrelevant hypotheses and overstate evidence against those hypotheses. These problems are not however properties of P-values but are faults of researchers who focus on null hypotheses and overstate evidence based on misperceptions that p = 0.05 represents enough evidence to reject hypotheses …
Abstract
EDITORIAL: The editorial was written by the three editors acting as individuals and reflects their scientific views not an endorsed position of the American Statistical Association.Some of you expl...
15 Appendix: Technical Details
15.1 Mathematical Formulation
For a normally distributed estimator with standard error , the confidence limits at level are:
The CI-function plots these limits across all values of .
For t-distributed estimators (when degrees of freedom are specified):
15.2 Exponentiated Coefficients
When eform is specified, computations occur on the log scale:
- Transform: with
- Compute CI limits on log scale
- Back-transform:
This ensures symmetric intervals on the log scale and proper geometric interpretation.
Last updated: 2026-09-13 Source code: Available on request License: Free for academic and non-commercial use
Citation
@article{rafi2024,
author = {Rafi, Zad and R, Zad},
title = {Computing {Confidence} {Interval} {Functions} with
Cifunction},
journal = {Less Likely},
date = {2024-03-23},
url = {https://lesslikely.com/statistics/cifunction},
langid = {en-US},
abstract = {The cifunction package for Stata computes and graphically
displays all possible confidence intervals around a point estimate,
creating what’s known as a confidence interval function, confidence
curve, p-value function, or consonance interval. This approach
conveys more information than traditional single-level confidence
intervals by showing the full range of values compatible with the
data at all confidence levels.}
}
Linked from (6)
- All Posts
- Blog § All Posts
- Constructing Likelihood Functions in R, Stata, Python, Julia, MATLAB, and SQL § Validation status SSC module; conventions per the cifunction guide
- How to Be a Good Collaborator to a Statistician and a Data Engineer § What Statisticians and Data Engineers Owe Back …han as continuous evidence throws away most of what the analysis produced — the case for S-values and the full compatibility/consonance function rather than a single dichotomized interval.
- Site Map § Search & Navigation
- Statistics § Latest Statistics Articles
Comments