Source

Fleiss, J.L. Statistical Methods for Rates and Proportions, pp. 13-15, 1981.

Anscombe, F.J. The transformation of Poisson, binomial, negative binomial data. Biometrika 35, 246–254, 1948.

Description

The One Arm Binomial calculator computes an estimate of either sample size or power for the one sample binomial problem, and corresponding critical values (reject if ≥ critical value). The calculator also computes exact power and alpha for the given null and alternative proportions, sample size, and criitical values. Note that sample size and critical values can be changed and exact alpha/power re-calculated.

Critical values and sample size (if requested) are calculated using a normal approximation to the binomial. Final exact power and alpha are calculated using the binomial distribution function.

The calculator uses the arcsin transformation to achieve better small sample properties based on methodology described in many sources, including Anscombe (Biometrika 35, 1948).

Running the Program

Enter the type of calculation to be performed: either estimate sample size or estimate power. Enter the input items listed below. Some items have initial default values.

For some design scenarios, a design may not be produced with an exact \(\alpha\) that is less than or equal to the significance level input by the user while also maintaining exact power greater than or equal to the desired power input by the user. In such cases, if the exact \(\alpha\) is at least 20% greater than the significance level desired by the user, a warning message is displayed. The user may also subsequently input their choice of critical values to generate other potential design scenarios.

Input Items

The user is prompted for values to the following items. For items that have initial default values set, the values are given in parentheses.

Output Items

Actions

Sample size and critical values can be changed after the calculation is completed. Choose “re-calculate exact alpha/power” to get new exact power and alpha after values are manipulated.

Interpreting Outputs

For \(p_{0}\) < \(p_{a}\) and 2-sided test, reject \(H_{0}\) if number of responses is < the lower critical value or \(\ge\) upper critical value.

For \(p_{0}\) < \(p_{a}\) and 1-sided test, reject \(H_{0}\) if number of responses \(\ge\) the upper critical value.

For \(p_{a}\) < \(p_{0}\) and 2-sided test, reject \(H_{0}\) if number of responses is < the lower critical value or \(\ge\) upper critical value.

For \(p_{a}\) < \(p_{0}\) and 1-sided test, reject \(H_{0}\) if number of responses < the lower critical value.

Statistical Code

The program is written in R.

View Code


function(calc, test_type, sided, p0, p1, alpha, powersp, nsp, clsp, chsp) {
  
  ## Calculate Z values for one- or two-sided tests
  z_alpha = qnorm(1 - alpha / sided)
  
  ## Arcsine transformations
  p0_arc = asin(sqrt(p0))
  p1_arc = asin(sqrt(p1))
  
  ## Determine the sample size & power
  if (calc == "Sample Size") {
    ## Use the specified power
    power = powersp

    ## Compute N with arcsine transform
    z_beta = qnorm(powersp)
    sqrt_n = (z_alpha + z_beta) / (2 * (p1_arc - p0_arc))
    n = round((sqrt_n ^ 2 + 0.5), 0)
    sd = 0.5 / sqrt(n)
  } else {
    ## Use the specified N
    n = nsp
    sd = 0.5 / sqrt(n)

    ## Compute approximate power for given sample size N
    if (p1 >= p0) {
      power = pnorm((p1_arc - p0_arc) / sd - z_alpha)
    } else if (p0 > p1) {
      power = pnorm((p0_arc - p1_arc) / sd - z_alpha)
    }
    power = format(round(power, 2), digits = 2)
  }
  
  ## Calculate low & high crit values
  if (test_type == "Exact") {
    ## If exact test was requested, use user inputs for low & high crit values
    crit_low = clsp
    crit_high = chsp
  } else {
    ## Otherwise, derive the low & high crit values
    p0_low_arc = p0_arc - (z_alpha * sd)
    p0_high_arc = p0_arc + (z_alpha * sd)
    
    ## Back transform
    p0_low = (sin(p0_low_arc)) ^ 2
    p0_high = (sin(p0_high_arc)) ^ 2
    
    ## Compute critical values
    crit_low = floor((p0_low * n) + 0.5)
    crit_high = floor((p0_high * n) + 0.5)
    if (sided == 1) { 
      if (p1 >= p0) {
        crit_low = NA ## Not needed for one-sided test where p1 > p0
      } else {
        crit_high = NA
      }
    }
  }
  
  ## Compute exact power, alpha
  if (sided == 1) {
    if (p1 >= p0) {
      power_exact = 1 - pbinom(crit_high - 1, n, p1)
      alpha_exact = 1 - pbinom(crit_high - 1, n, p0)
    } else {
      power_exact = pbinom(crit_low, n, p1)
      alpha_exact = pbinom(crit_low, n, p0)
    }
  } else {
    power_exact = 1 - (pbinom(crit_high - 1, n, p1) - pbinom(crit_low, n, p1))
    if (p1 >= p0) {
      # For 2-sided alpha where lower critical value is 0, select a result with parts of critical region in both tails
      # (e.g. true 2-sided critical region) if mass in lower tail is <= alpha/2
      # Otherwise, allow calculator to select one-sided critical region all in upper part of tail
      if (((pbinom(crit_low, n, p0) <= alpha / 2) && crit_low == 0) | crit_low > 0) {
        alpha_exact = pbinom(crit_low, n, p0) + (1 - pbinom(crit_high - 1, n, p0))
      } else {
        alpha_exact = (1 - pbinom(crit_high - 1, n, p0))
      }
    } else {
      alpha_exact = 1 - pbinom(crit_high - 1, n, p0) + (pbinom(crit_low, n, p0))
    }
  }
  
  result = list(n = n,
                power = power,
                lowerci = crit_low,
                upperci = crit_high,
                exact_alpha = format(round(alpha_exact, 4), digits = 4),
                exact_power = format(round(power_exact, 4), digits = 4))

  return(jsonlite::toJSON(result, pretty = TRUE))
}