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)"))
#> Can not set Stata directory, try using -statapath(
#> > )- option
#> 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)"))
#> Can not set Stata directory, try using -statapath(
#> > )- option
#> r(601);
#>
#>
#> (Doll and Hill (1966))
#>
#> 3. }
#>
#> 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% con
#> > f. 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% con
#> > f. 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% con
#> > f. 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% con
#> > f. 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)"))
#> Can not set Stata directory, try using -statapath(
#> > )- option
#> r(601);
#>
#>
#>
#>
#> > Proportion
#> | Exposed Unexposed | T
#> > otal 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 | T
#> > otal 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.1
#> > 23936 7.151794 (Woolf)
#> Attr. frac. ex. | .6472868 | .11
#> > 02698 .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)"))
#> Can not set Stata directory, try using -statapath(
#> > )- option
#> 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)
#> Can not set Stata directory, try using -statapath(
#> > )- option
#> 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
15 Appendix: Technical Details
15.1 Mathematical Formulation
For a normally distributed estimator \hat{\theta} with standard error SE(\hat{\theta}), the confidence limits at level (1-\alpha) are:
\hat{\theta} \pm z_{1-\alpha/2} \cdot SE(\hat{\theta})
The CI-function plots these limits across all values of \alpha \in [0, 1].
For t-distributed estimators (when degrees of freedom are specified):
\hat{\theta} \pm t_{1-\alpha/2, df} \cdot SE(\hat{\theta})
15.2 Exponentiated Coefficients
When eform is specified, computations occur on the log scale:
- Transform: \log(\hat{\theta}) with SE(\log(\hat{\theta}))
- Compute CI limits on log scale
- Back-transform: \exp(limits)
This ensures symmetric intervals on the log scale and proper geometric interpretation.
Last updated: 2026-05-26 Source code: Available on request License: Free for academic and non-commercial use
Comments
Comments are loaded on demand so they don’t slow down the initial page render.