The first method to estimate sample size for the CMH test was introduced by @Gail1973 using a least squares method. @Munoz1984 later produced sample size estimators useful in the special case when both margins are fixed. However, this is often not the case in retrospective case-control designs. As such, @Woolson1986 introduced a calculation using the weighted difference between two binomial distributions, which assumes only one margin to be fixed. This was corroborated by @Wittes1987 in their paper a year later. Later still, @Nam1992 improved upon that calculation by introducing a coefficient to address continuity corrected CMH tests.
The methods included in the package are based on calculations derived by @Woolson1986 for uncorrected statistics and @Nam1992 for continuity corrected statistics. A slightly more precise power calculation is used based on @Wittes1987, but it is functionally equivalent to the calculation by @Woolson1986.
Starting with the example first used by @Woolson1986 and then revisited by @Nam1992, we will explore the usage of the central function of the samplesizeCMH
{.r} package, the power.cmh.test()
{.r} function.
This was a case--control study which looked at whether there was an association between colon cancer and chlorinated drinking water among males in Iowa, stratified by age. There were four age categories, 20--54 years, 55--69 years, 70--79 years, and 80--84 years; therefore the number of levels of the stratifying variable $J$ = 4. The relative proportion of each age group to the total sample is as follows: $t_1$ = 0.10, $t_2$ = 0.40, $t_3$ = 0.35, and $t_4$ = 0.15. The National Collaborative Bladder Cancer Study showed that exposure rate for controls for each age stratum, denoted by $\pi_{2j}$ (where the subscript '2' indicates second column proportions and $j$ is the stratum), was $\pi_{21}$ = 0.75, $\pi_{22}$ = 0.70, $\pi_{23}$ = 0.65, and $\pi_{24}$ = 0.60. Level of significance was set at 0.05 and desired power was 90% with an effect size of 3. They matched equal number of cases and controls in each stratum, i.e., $s_1=s_2=s_3=s_4=$ 0.5.
We will go over several variations on the experimental design to explore the usage of the power.cmh.test()
{.r} function.
Suppose that the researchers first decided to use the original CMH calculation, ignoring contnuity correction. As such, the parameter correct
is set to FALSE
{.r}. We see that the researcher has put in the control exposure proportions as a vector (p2
), the effect size has been given (theta
), and a vector of relative stratum sizes has been assigned (t
). Since there are equal numbers of cases and controls for each group, the s
parameter is not required. Only p1
and p2
or one of the proportions and a theta
are required to carry out the calculation. The number of strata ($J$) is inferred from the maximum vector length of p1
, p2
, or theta
.
library(samplesizeCMH) sample_size_uncorrected <- power.cmh.test( p2 = c(0.75,0.70,0.65,0.60), theta = 3, power = 0.9, t = c(0.10,0.40,0.35,0.15), alternative = "greater", correct = FALSE ) print(sample_size_uncorrected, detail = FALSE)
Note that the detail = FALSE
{.r} parameter was passed to the print
{.r} method to reduce output.
After further reading, the researcher has now determined that a continuity correction would be appropriate when performing the CMH test (the default of the mantaelhaen.test()
{.r} is correct = TRUE
{.r}). The correct
parameter in the code below has be flipped to TRUE
{.r} to take continuity correction into account.
sample_size_corrected <- power.cmh.test( p2 = c(0.75,0.70,0.65,0.60), theta = 3, power = 0.9, t = c(0.10,0.40,0.35,0.15), alternative = "greater", correct = TRUE ) print(sample_size_corrected, n.frac = TRUE)
We see that the N
has increased by $\approx$ 12%, as is expected when continuity correction is taken into account. The n.frac
option was used to get fractional n's, rather than rounding the the next whole number.
Consider now that the researcher performed some preparatory work and has found that the number of cases available is much fewer than the number of available controls. In fact, it is very difficult to find cases that meet the inclusion criteria, but is relatively easy to find controls that meet the inclusion criteria. Wanting to leverage all of the available data, an adjustment was be made to the sample size calculation performed earlier by including the s
parameter. The design now supposes two controls matched to each case.
power.cmh.test( p2 = c(0.75,0.70,0.65,0.60), s = 1/3, theta = 3, power = 0.9, t = c(0.10,0.40,0.35,0.15), alternative = "greater", correct = TRUE )
Note that effective N has increased by 24 subjects. The CMH test is at optimum efficiency when s
is balanced. Therefore, altering the case/control ratio should be implemented only when there is a compelling reason to do so, such as difficulty in finding cases or prohibitive costs.
Let's take a moment to look at the partial table of stratum $j$ = 1. Given the information above, we can reconstruct this table to better understand the question at hand. We can also use this as an opportunity to use some of the peripheral functions included in the samplesizeCMH
{.r} package.
The proportion of controls exposed to chlorinated drinking water was $\pi_{21}$ = 0.75. It follows then that the complementary column proportion is 0.25. The table below shows column percents.
| |Case | Control | ------------|:---:|:-------:| Exposed | ? | 0.75 Not Exposed | ? | 0.25
Using the effect.size()
{.r} function, we can use the expected exposure rate of control to estimate expected exposure rate of cases.
effect.size(0.75,3)
We can now use that to fill in the remainder of our table.
| |Case | Control | ------------|:---:|:-------:| Exposed | 0.90| 0.75 Not Exposed | 0.10| 0.25
To determine the odds of exposure for the two groups, we can use prop2odds()
{.r}.
# Control prop2odds(0.75) # Case prop2odds(0.9)
We can also use either row or column proportions to calculate the odds ratio for a 2 $\times$ 2 table.
props2theta(0.90,0.75)
We see that this brings us back to our specified effect size, theta
= 3, which was used in the sample size calculaion.
There are several other peripheral functions in this package to interconvert between proportions, odds, relative risk, and odds ratios. Use help("odds.and.proportions", "samplesizeCMH")
{.r} to find out more.
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.