The package includes functions for power analysis and sample size calculation for Welch and Hsu (Hedderich and Sachs 2018) t tests including Monte-Carlo simulations of empirical power and type-I-error. In addition, power and sample size calculation for Wilcoxon rank sum and signed rank tests via Monte-Carlo simulations can be performed. Moreover, power and sample size required for the evaluation of a diagnostic test(-system) (Flahault, Cadilhac, and Thomas 2005; Dobbin and Simon 2007) as well as for a single proportion (Fleiss, Levin, and Paik 2003), comparing two negative binomial rates (Zhu and Lakkis 2014), ANCOVA (Shieh 2020), reference ranges (Jennen-Steinmetz and Wellek 2005), and multiple primary endpoints (Sozu et al. 2015).
We first load the package.
The computation of the required sample size for investigating a single proportion can be determined via the respective test or confidence interval (Fleiss, Levin, and Paik 2003). First, we consider the asymptotic test.
##
## Power calculation for testing a given proportion (with continuity correction)
##
## n = 203.7246
## delta = 0.1
## p1 = 0.4
## p0 = 0.5
## sig.level = 0.05
## exact.sig.level = 0.04205139
## power = 0.8
## exact.power = 0.8008049
## alternative = two.sided
##
## NOTE: n = total sample size
##
## Power calculation for testing a given proportion
##
## n = 193.8473
## delta = 0.1
## p1 = 0.4
## p0 = 0.5
## sig.level = 0.05
## exact.sig.level = 0.05228312
## power = 0.8
## exact.power = 0.8067065
## alternative = two.sided
##
## NOTE: n = total sample size
Next, we compute the sample size via the respective asymptotic confidence interval.
##
## Sample size calculation by method of wald-cc
##
## n = 202.1865
## prop = 0.4
## width = 0.14
## conf.level = 0.95
##
## NOTE: Two-sided confidence interval
##
## Sample size calculation by method of wald
##
## n = 188.1531
## prop = 0.4
## width = 0.14
## conf.level = 0.95
##
## NOTE: Two-sided confidence interval
For computing the sample size of the Welch t-test, we only consider the situation of equal group size (balanced design).
## identical results as power.t.test, since sd = sd1 = sd2 = 1
power.welch.t.test(n = 20, delta = 1)
##
## Two-sample Welch t test power calculation
##
## n = 20
## delta = 1
## sd1 = 1
## sd2 = 1
## sig.level = 0.05
## power = 0.8689528
## alternative = two.sided
##
## NOTE: n is number in *each* group
##
## Two-sample Welch t test power calculation
##
## n = 22.0211
## delta = 1
## sd1 = 1
## sd2 = 1
## sig.level = 0.05
## power = 0.9
## alternative = two.sided
##
## NOTE: n is number in *each* group
##
## Two-sample Welch t test power calculation
##
## n = 17.84713
## delta = 1
## sd1 = 1
## sd2 = 1
## sig.level = 0.05
## power = 0.9
## alternative = one.sided
##
## NOTE: n is number in *each* group
##
## Two-sample Welch t test power calculation
##
## n = 14.53583
## delta = 1
## sd1 = 0.5
## sd2 = 1
## sig.level = 0.05
## power = 0.9
## alternative = two.sided
##
## NOTE: n is number in *each* group
For computing the sample size of the Hsu t-test (Hedderich and Sachs 2018), we only consider the situation of equal group size (balanced design).
##
## Two-sample Hsu t test power calculation
##
## n = 20
## delta = 1
## sd1 = 1
## sd2 = 1
## sig.level = 0.05
## power = 0.8506046
## alternative = two.sided
##
## NOTE: n is number in *each* group
##
## Two-sample Hsu t test power calculation
##
## n = 23.02186
## delta = 1
## sd1 = 1
## sd2 = 1
## sig.level = 0.05
## power = 0.9
## alternative = two.sided
##
## NOTE: n is number in *each* group
##
## Two-sample Hsu t test power calculation
##
## n = 18.5674
## delta = 1
## sd1 = 1
## sd2 = 1
## sig.level = 0.05
## power = 0.9
## alternative = one.sided
##
## NOTE: n is number in *each* group
##
## Two-sample Welch t test power calculation
##
## n = 53.86822
## delta = 0.5
## sd1 = 0.5
## sd2 = 1
## sig.level = 0.05
## power = 0.9
## alternative = two.sided
##
## NOTE: n is number in *each* group
##
## Two-sample Hsu t test power calculation
##
## n = 54.49421
## delta = 0.5
## sd1 = 0.5
## sd2 = 1
## sig.level = 0.05
## power = 0.9
## alternative = two.sided
##
## NOTE: n is number in *each* group
With function power.ancova one can compute power and sample size in ANCOVA designs (Shieh 2020). The default matrix of contrasts used in the function is
## [,1] [,2] [,3]
## [1,] 1 -1 0
## [2,] 1 0 -1
## [,1] [,2] [,3] [,4]
## [1,] 1 -1 0 0
## [2,] 1 0 -1 0
## [3,] 1 0 0 -1
We use the example provided in Table 9.7 of Maxwell and Delaney (2004).
## Example from Maxwell and Delaney (2004) according to Shieh (2020)
power.ancova(mu=c(7.5366, 11.9849, 13.9785), var = 29.0898, power = 0.8)
##
## ANCOVA power calculation
##
## ns = 14.29481, 14.29481, 14.29481
## mu = 7.5366, 11.9849, 13.9785
## var = 29.0898
## nr.covs = 1
## sig.level = 0.05
## power = 0.8
##
## NOTE: Total sample size: 45
##
## ANCOVA power calculation
##
## ns = 15, 15, 15
## mu = 7.5366, 11.9849, 13.9785
## var = 29.0898
## nr.covs = 1
## sig.level = 0.05
## power = 0.8219894
##
## NOTE: Total sample size: 45
##
## ANCOVA power calculation
##
## ns = 18.32456, 18.32456, 18.32456
## mu = 7.5366, 11.9849, 13.9785
## var = 29.0898
## nr.covs = 1
## sig.level = 0.05
## power = 0.9
##
## NOTE: Total sample size: 57
##
## ANCOVA power calculation
##
## ns = 19, 19, 19
## mu = 7.5366, 11.9849, 13.9785
## var = 29.0898
## nr.covs = 1
## sig.level = 0.05
## power = 0.9115114
##
## NOTE: Total sample size: 57
Based on the reported adjusted group means and error variance, a (total) sample size of 45 is required to achieve a power of at least 80%. The calculated power is 82.2%. With a sample size of 57 the power will be at least 90%, where the calculated power is 91.2%.
Introducing additional covariates (random covariate model) will increase the required sample size.
##
## ANCOVA power calculation
##
## ns = 14.65509, 14.65509, 14.65509
## mu = 7.5366, 11.9849, 13.9785
## var = 29.0898
## nr.covs = 2
## sig.level = 0.05
## power = 0.8
##
## NOTE: Total sample size: 45
##
## ANCOVA power calculation
##
## ns = 15.01403, 15.01403, 15.01403
## mu = 7.5366, 11.9849, 13.9785
## var = 29.0898
## nr.covs = 3
## sig.level = 0.05
## power = 0.8
##
## NOTE: Total sample size: 48
##
## ANCOVA power calculation
##
## ns = 15.72837, 15.72837, 15.72837
## mu = 7.5366, 11.9849, 13.9785
## var = 29.0898
## nr.covs = 5
## sig.level = 0.05
## power = 0.8
##
## NOTE: Total sample size: 48
##
## ANCOVA power calculation
##
## ns = 17.4965, 17.4965, 17.4965
## mu = 7.5366, 11.9849, 13.9785
## var = 29.0898
## nr.covs = 10
## sig.level = 0.05
## power = 0.8
##
## NOTE: Total sample size: 54
We can also calculate the per group sample sizes for an imbalanced design.
power.ancova(mu=c(7.5366, 11.9849, 13.9785), var = 29.0898, power = 0.8,
group.ratio = c(1, 1.25, 1.5))
##
## ANCOVA power calculation
##
## ns = 12.25390, 15.31738, 18.38085
## mu = 7.5366, 11.9849, 13.9785
## var = 29.0898
## nr.covs = 1
## sig.level = 0.05
## power = 0.8
##
## NOTE: Total sample size: 48
power.ancova(n = c(13, 16, 19), mu=c(7.5366, 11.9849, 13.9785), var = 29.0898,
group.ratio = c(1, 1.25, 1.5))
##
## ANCOVA power calculation
##
## ns = 13, 16, 19
## mu = 7.5366, 11.9849, 13.9785
## var = 29.0898
## nr.covs = 1
## sig.level = 0.05
## power = 0.8266307
##
## NOTE: Total sample size: 48
power.ancova(mu=c(7.5366, 11.9849, 13.9785), var = 29.0898, power = 0.8,
group.ratio = c(1, 0.8, 2/3))
##
## ANCOVA power calculation
##
## ns = 16.87449, 13.49959, 11.24966
## mu = 7.5366, 11.9849, 13.9785
## var = 29.0898
## nr.covs = 1
## sig.level = 0.05
## power = 0.8
##
## NOTE: Total sample size: 43
power.ancova(n = c(17, 14, 12), mu=c(7.5366, 11.9849, 13.9785), var = 29.0898,
group.ratio = c(1, 0.8, 2/3))
##
## ANCOVA power calculation
##
## ns = 17, 14, 12
## mu = 7.5366, 11.9849, 13.9785
## var = 29.0898
## nr.covs = 1
## sig.level = 0.05
## power = 0.8034654
##
## NOTE: Total sample size: 43
We get a smaller total sample size with an imbalanced design (43 instead of 45).
For computing the sample size of these tests, we offer a function that performs Monte-Carlo simulations to determine their (empirical) power.
rx <- function(n) rnorm(n, mean = 0, sd = 1)
ry <- function(n) rnorm(n, mean = 0.5, sd = 1)
## two-sample
sim.ssize.wilcox.test(rx = rx, ry = ry, n.max = 100, iter = 1000)
##
## Wilcoxon rank sum test
##
## n = 10, 20, 30, 40, 50, 60, 70
## rx = rnorm(n, mean = 0, sd = 1)
## ry = rnorm(n, mean = 0.5, sd = 1)
## sig.level = 0.05
## emp.power = 0.160, 0.319, 0.472, 0.573, 0.661, 0.755, 0.816
## alternative = two.sided
##
## NOTE: n is number in *each* group
sim.ssize.wilcox.test(rx = rx, ry = ry, n.min = 65, n.max = 70,
step.size = 1, iter = 1000, BREAK = FALSE)
##
## Wilcoxon rank sum test
##
## n = 65, 66, 67, 68, 69, 70
## rx = rnorm(n, mean = 0, sd = 1)
## ry = rnorm(n, mean = 0.5, sd = 1)
## sig.level = 0.05
## emp.power = 0.789, 0.775, 0.797, 0.800, 0.806, 0.798
## alternative = two.sided
##
## NOTE: n is number in *each* group
##
## Two-sample t test power calculation
##
## n = 63.76576
## delta = 0.5
## sd = 1
## sig.level = 0.05
## power = 0.8
## alternative = two.sided
##
## NOTE: n is number in *each* group
##
## Wilcoxon signed rank test
##
## n = 10, 20, 30, 40
## rx = rnorm(n, mean = 0.5, sd = 1)
## sig.level = 0.05
## emp.power = 0.294, 0.552, 0.719, 0.858
## alternative = two.sided
##
## NOTE: n is number in *each* group
sim.ssize.wilcox.test(rx = ry, type = "one.sample", n.min = 33,
n.max = 38, step.size = 1, iter = 1000, BREAK = FALSE)
##
## Wilcoxon signed rank test
##
## n = 33, 34, 35, 36, 37, 38
## rx = rnorm(n, mean = 0.5, sd = 1)
## sig.level = 0.05
## emp.power = 0.777, 0.794, 0.800, 0.801, 0.819, 0.841
## alternative = two.sided
##
## NOTE: n is number in *each* group
##
## One-sample t test power calculation
##
## n = 33.3672
## delta = 0.5
## sd = 1
## sig.level = 0.05
## power = 0.8
## alternative = two.sided
## two-sample
rx <- function(n) rgamma(n, scale = 2, shape = 1.5)
ry <- function(n) rgamma(n, scale = 4, shape = 1.5) # equal shape
## two-sample
sim.ssize.wilcox.test(rx = rx, ry = ry, n.max = 100, iter = 1000)
##
## Wilcoxon rank sum test
##
## n = 10, 20, 30
## rx = rgamma(n, scale = 2, shape = 1.5)
## ry = rgamma(n, scale = 4, shape = 1.5)
## sig.level = 0.05
## emp.power = 0.322, 0.622, 0.822
## alternative = two.sided
##
## NOTE: n is number in *each* group
sim.ssize.wilcox.test(rx = rx, ry = ry, n.min = 25, n.max = 30,
step.size = 1, iter = 1000, BREAK = FALSE)
##
## Wilcoxon rank sum test
##
## n = 25, 26, 27, 28, 29, 30
## rx = rgamma(n, scale = 2, shape = 1.5)
## ry = rgamma(n, scale = 4, shape = 1.5)
## sig.level = 0.05
## emp.power = 0.754, 0.773, 0.753, 0.782, 0.807, 0.829
## alternative = two.sided
##
## NOTE: n is number in *each* group
For practical applications we recommend to use a higher number of iterations. For more detailed examples we refer to the help page of the function.
When we consider two negative binomial rates (Zhu and Lakkis 2014), we can compute sample size or power applying function power.nb.test.
## examples from Table III in Zhu and Lakkis (2014)
power.nb.test(mu0 = 5.0, RR = 2.0, theta = 1/0.5, duration = 1, power = 0.8, approach = 1)
##
## Power calculation for comparing two negative binomial rates
##
## n = 22.37386
## n1 = 22.37386
## mu0 = 5
## RR = 2
## theta = 2
## duration = 1
## sig.level = 0.05
## power = 0.8
## alternative = two.sided
##
## NOTE: n = sample size of control group, n1 = sample size of treatment group
##
## Power calculation for comparing two negative binomial rates
##
## n = 21.23734
## n1 = 21.23734
## mu0 = 5
## RR = 2
## theta = 2
## duration = 1
## sig.level = 0.05
## power = 0.8
## alternative = two.sided
##
## NOTE: n = sample size of control group, n1 = sample size of treatment group
##
## Power calculation for comparing two negative binomial rates
##
## n = 20.85564
## n1 = 20.85564
## mu0 = 5
## RR = 2
## theta = 2
## duration = 1
## sig.level = 0.05
## power = 0.8
## alternative = two.sided
##
## NOTE: n = sample size of control group, n1 = sample size of treatment group
Given an expected sensitivity and specificity we can compute sample size, power (assurance probability), delta or significance level (error probability) of diagnostic test (Flahault, Cadilhac, and Thomas 2005). The calculation is based on a one-sided confidence interval.
## see n2 on page 1202 of Chu and Cole (2007)
ssize.sens.ci(sens = 0.99, delta = 0.14, power = 0.95) # 40
##
## Diagnostic test exact power calculation
##
## sens = 0.99
## n = 40
## n1 = 40
## delta = 0.14
## sig.level = 0.05
## power = 0.95
## prev = NULL
##
## NOTE: n is number of cases, n1 is number of controls
##
## Diagnostic test exact power calculation
##
## sens = 0.99
## n = 43
## n1 = 43
## delta = 0.13
## sig.level = 0.05
## power = 0.95
## prev = NULL
##
## NOTE: n is number of cases, n1 is number of controls
##
## Diagnostic test exact power calculation
##
## spec = 0.99
## n = 47
## n1 = 47
## delta = 0.12
## sig.level = 0.05
## power = 0.95
## prev = NULL
##
## NOTE: n is number of controls, n1 is number of cases
Given an expected AUC we can compute sample size, power (assurance probability), delta or significance level (error probability) of the AUC based on a one-sided confidence interval.
##
##
##
## AUC = 0.9
## n = 55.75181
## n1 = 55.75181
## delta = 0.1
## sig.level = 0.05
## power = 0.95
## prev = 0.5
##
## NOTE: n is number of cases, n1 is number of controls
The sample size planning for developing binary classifiers in case of high dimensional data, we can apply function ssize.pcc, which is based on the probability of correct classification (PCC) (Dobbin and Simon 2007).
## see Table 2 of Dobbin et al. (2008)
g <- 0.1
fc <- 1.6
ssize.pcc(gamma = g, stdFC = fc, nrFeatures = 22000)
##
## Sample Size Planning for Developing Classifiers Using High Dimensional Data
##
## gamma = 0.1
## prev = 0.5
## nrFeatures = 22000
## n1 = 21
## n2 = 21
##
## NOTE: n1 is number of cases, n2 is number of controls
We can apply function ssize.reference.range to determine the sample size required for a study planned to establish a reference range. The parametric approach assumes a normal distribution whereas the non-parametric approach only assumes a continuous distribution.
ssize.reference.range(delta = 0.01, ref.prob = 0.95, conf.prob = 0.9,
method = "parametric", exact = TRUE)
##
## Reference range sample size calculation
##
## n = 271.6691
## delta = 0.01
## ref.prob = 0.95
## conf.prob = 0.9
## alternative = two.sided
##
## NOTE: Exact method for normal distribution
ssize.reference.range(delta = 0.01, ref.prob = 0.95, conf.prob = 0.9,
method = "parametric", exact = FALSE)
##
## Reference range sample size calculation
##
## n = 269.9241
## delta = 0.01
## ref.prob = 0.95
## conf.prob = 0.9
## alternative = two.sided
##
## NOTE: Approximate method for normal distribution
ssize.reference.range(delta = 0.01, ref.prob = 0.95, conf.prob = 0.9,
method = "nonparametric", exact = TRUE)
##
## Reference range sample size calculation
##
## n = 635.2654
## delta = 0.01
## ref.prob = 0.95
## conf.prob = 0.9
## alternative = two.sided
##
## NOTE: Exact non-parametric method
ssize.reference.range(delta = 0.01, ref.prob = 0.95, conf.prob = 0.9,
method = "nonparametric", exact = FALSE)
##
## Reference range sample size calculation
##
## n = 659.4762
## delta = 0.01
## ref.prob = 0.95
## conf.prob = 0.9
## alternative = two.sided
##
## NOTE: Approximate non-parametric method
We can also calculate the sample size for one-sided reference ranges.
ssize.reference.range(delta = 0.015, ref.prob = 0.95, conf.prob = 0.9,
method = "parametric", exact = TRUE,
alternative = "one.sided")
##
## Reference range sample size calculation
##
## n = 301.617
## delta = 0.015
## ref.prob = 0.95
## conf.prob = 0.9
## alternative = one.sided
##
## NOTE: Exact method for normal distribution
We demonstrate how to calculate the sample size for a trial with two co-primary endpoints with known covariance.
Sigma <- matrix(c(1, 0.8, 0.8, 1), nrow = 2)
power.mpe.known.var(K = 2, delta = c(0.25, 0.4), Sigma = Sigma,
sig.level = 0.025, power = 0.8)
##
## Power calculation for multiple co-primary endpoints (covariance known)
##
## n = 251.2079
## delta = 0.25, 0.40
## SD = 1, 1
## rho = 0.8
## sig.level = 0.025
## power = 0.8
##
## Sigma =
## [,1] [,2]
## [1,] 1.0 0.8
## [2,] 0.8 1.0
##
## NOTE: n is number in *each* group
## equivalent: specify SDs and correlation rho
power.mpe.known.var(K = 2, delta = c(0.25, 0.4), SD = c(1,1), rho = 0.8,
sig.level = 0.025, power = 0.8)
##
## Power calculation for multiple co-primary endpoints (covariance known)
##
## n = 251.2079
## delta = 0.25, 0.40
## SD = 1, 1
## rho = 0.8
## sig.level = 0.025
## power = 0.8
##
## Sigma =
## [,1] [,2]
## [1,] 1.0 0.8
## [2,] 0.8 1.0
##
## NOTE: n is number in *each* group
Next, we show how to calculate the sample size for a trial with two co-primary endpoints with unknown covariance. Here, we follow three steps to determine the sample size.
Step 1: As we need starting values for our algorithm that
computes the sample size in this case, we first act as if the covariance
would be known and compute the sample size by applying our function
power.mpe.known.var
.
Step 2: The resulting value of n
is considered as
lower bound for the sample size in case of unknown covariance and is
used as n.min
in function
power.mpe.unkown.var
. Moreover, we specify a reasonable
n.max
, which must be larger than
n.min
.
Step 3: Finally, by using the arguments from the step 2, we can compute the sample size for the situation with unknown covariance.
## Step 1:
power.mpe.known.var(K = 2, delta = c(0.5, 0.4), Sigma = Sigma,
sig.level = 0.025, power = 0.8)
##
## Power calculation for multiple co-primary endpoints (covariance known)
##
## n = 100.0826
## delta = 0.5, 0.4
## SD = 1, 1
## rho = 0.8
## sig.level = 0.025
## power = 0.8
##
## Sigma =
## [,1] [,2]
## [1,] 1.0 0.8
## [2,] 0.8 1.0
##
## NOTE: n is number in *each* group
## Step 2 + 3:
Sigma <- matrix(c(1, 0.5, 0.5, 1), nrow = 2)
power.mpe.unknown.var(K = 2, delta = c(0.5, 0.4), Sigma = Sigma,
sig.level = 0.025, power = 0.8,
n.min = 105, n.max = 120)
## Current precision: -0.004521862
## Current precision: 0.05232739
## Current precision: 0.0007625384
## Current precision: 5.571479e-05
## Current precision: -0.0002569758
## Current precision: -0.0001545662
## Current precision: 2.350941e-05
## Current precision: -0.00025997
## Current precision: 0.0003175776
## Current precision: -0.0001569394
## Current precision: -0.0001571391
## Current precision: -0.0003360948
## Current precision: 6.854054e-05
##
## Power calculation for multiple co-primary endpoints (covariance unknown)
##
## n = 106.0202
## delta = 0.5, 0.4
## SD = 1, 1
## rho = 0.5
## sig.level = 0.025
## power = 0.8
##
## Sigma =
## [,1] [,2]
## [1,] 1.0 0.5
## [2,] 0.5 1.0
##
## NOTE: n is number in *each* group
## equivalent: specify SDs and correlation rho
power.mpe.unknown.var(K = 2, delta = c(0.5, 0.4), SD = c(1,1), rho = 0.5,
sig.level = 0.025, power = 0.8,
n.min = 105, n.max = 120)
## Current precision: -0.003838119
## Current precision: 0.05231136
## Current precision: 0.0004913149
## Current precision: -0.001156639
## Current precision: -0.0009737845
## Current precision: -0.0005025679
## Current precision: -0.0002141294
## Current precision: 0.0001505083
## Current precision: 0.0006028865
## Current precision: -0.0008063434
## Current precision: 0.000183268
## Current precision: -0.0001798484
## Current precision: -0.0005059941
## Current precision: -3.131932e-05
##
## Power calculation for multiple co-primary endpoints (covariance unknown)
##
## n = 106.0202
## delta = 0.5, 0.4
## SD = 1, 1
## rho = 0.5
## sig.level = 0.025
## power = 0.8
##
## Sigma =
## [,1] [,2]
## [1,] 1.0 0.5
## [2,] 0.5 1.0
##
## NOTE: n is number in *each* group
We finally demonstrate how to calculate the sample size for a trial with two primary endpoints with known covariance, where the trial is designed to find a significant difference for at least one endpoint.
Sigma <- matrix(c(1, 0.3, 0.3, 1), nrow = 2)
power.mpe.atleast.one(K = 2, delta = c(0.2, 0.3), Sigma = Sigma,
power = 0.8, sig.level = 0.025)
##
## Power calculation for multiple primary endpoints for at least one endpoint
##
## n = 146.6651
## delta = 0.2, 0.3
## SD = 1, 1
## rho = 0.3
## sig.level = 0.025
## power = 0.8
##
## Sigma =
## [,1] [,2]
## [1,] 1.0 0.3
## [2,] 0.3 1.0
##
## NOTE: n is number in *each* group
## equivalent: specify SDs and correlation rho
power.mpe.atleast.one(K = 2, delta = c(0.2, 0.3), SD = c(1,1), rho = 0.3,
power = 0.8, sig.level = 0.025)
##
## Power calculation for multiple primary endpoints for at least one endpoint
##
## n = 146.6651
## delta = 0.2, 0.3
## SD = 1, 1
## rho = 0.3
## sig.level = 0.025
## power = 0.8
##
## Sigma =
## [,1] [,2]
## [1,] 1.0 0.3
## [2,] 0.3 1.0
##
## NOTE: n is number in *each* group
There are quite some discussions and various proposals, which test is the best under which circumstances when we want to compare the location (mean, median) of two groups (Fagerland and Sandvik 2009; Fagerland 2012; Sezer, Ozkip, and Yazici 2017). In addition, it is questioned whether pre-testing of assumptions is appropriate/useful at least from a practical point of view (Zimmerman 2004; Rasch, Kubinger, and Moder 2011; Rochon, Gondan, and Kieser 2012; Hoekstra, Kiers, and Johnson 2012).
We provide functions to simulate power and type-I-error of classical (Gosset 1908), Welch (Welch 1947) and Hsu (Hsu 1938) t-tests as well as of Wilcoxon-Mann-Whitney tests (Wilcoxon 1945; Mann and Whitney 1947).
## functions to simulate the data
## group 1
rx <- function(n) rnorm(n, mean = 0, sd = 1)
rx.H0 <- rx
## group 2
ry <- function(n) rnorm(n, mean = 3, sd = 3)
ry.H0 <- function(n) rnorm(n, mean = 0, sd = 3)
## theoretical results
power.welch.t.test(n = 10, delta = 3, sd1 = 1, sd2 = 3)
##
## Two-sample Welch t test power calculation
##
## n = 10
## delta = 3
## sd1 = 1
## sd2 = 3
## sig.level = 0.05
## power = 0.7794139
## alternative = two.sided
##
## NOTE: n is number in *each* group
##
## Two-sample Hsu t test power calculation
##
## n = 10
## delta = 3
## sd1 = 1
## sd2 = 3
## sig.level = 0.05
## power = 0.7611553
## alternative = two.sided
##
## NOTE: n is number in *each* group
## simulation
res.t <- sim.power.t.test(nx = 10, rx = rx, rx.H0 = rx.H0,
ny = 10, ry = ry, ry.H0 = ry.H0)
res.t
##
## Simulation Set-up
## nx = 10
## rx = function (n) , rnorm(n, mean = 0, sd = 1)
## rx.H0 = function (n) , rnorm(n, mean = 0, sd = 1)
## ny = 10
## ry = function (n) , rnorm(n, mean = 3, sd = 3)
## ry.H0 = function (n) , rnorm(n, mean = 0, sd = 3)
## sig.level = 0.05
## mu = 0
## alternative = two.sided
## iter = 10000
##
## Classical Two-sample t-Test
## emp.power = 0.8023
## emp.type.I.error = 0.0597
##
## Welch Two-sample t-Test
## emp.power = 0.7741
## emp.type.I.error = 0.0516
##
## Hsu Two-sample t-Test
## emp.power = 0.7564
## emp.type.I.error = 0.0444
res.w <- sim.power.wilcox.test(nx = 10, rx = rx, rx.H0 = rx.H0,
ny = 10, ry = ry, ry.H0 = ry.H0)
res.w
##
## Simulation Set-up
## nx = 10
## rx = function (n) , rnorm(n, mean = 0, sd = 1)
## rx.H0 = function (n) , rnorm(n, mean = 0, sd = 1)
## ny = 10
## ry = function (n) , rnorm(n, mean = 3, sd = 3)
## ry.H0 = function (n) , rnorm(n, mean = 0, sd = 3)
## sig.level = 0.05
## mu = 0
## alternative = two.sided
## iter = 10000
## conf.int = FALSE
## approximate = FALSE
## ties = FALSE
##
## Exact Wilcoxon-Mann-Whitney Test
## emp.power = 0.7542
## emp.type.I.error = 0.0594
##
## Asymptotic Wilcoxon-Mann-Whitney Test
## emp.power = 0.7542
## emp.type.I.error = 0.0594
For further investigation of the results, we provide some diagnostic plots.
We can also generate a volcano plot for the Wilcoxon-Mann-Whitney test, but this would require setting argument conf.int to TRUE, which would lead to a much higher computation time, hence we omitted it here. Furthermore, it is also possible to compute an approximate version of the test by setting argument approximate to TRUE (Hothorn et al. 2008) again by the cost of an increased computation time.
## R version 4.4.1 Patched (2024-09-18 r87189)
## Platform: x86_64-pc-linux-gnu
## Running under: Linux Mint 22
##
## Matrix products: default
## BLAS: /home/kohlm/RTOP/Rbranch/lib/libRblas.so
## LAPACK: /home/kohlm/RTOP/Rbranch/lib/libRlapack.so; LAPACK version 3.12.0
##
## locale:
## [1] LC_CTYPE=de_DE.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=de_DE.UTF-8 LC_COLLATE=C
## [5] LC_MONETARY=de_DE.UTF-8 LC_MESSAGES=de_DE.UTF-8
## [7] LC_PAPER=de_DE.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=de_DE.UTF-8 LC_IDENTIFICATION=C
##
## time zone: Europe/Berlin
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] MKpower_1.0
##
## loaded via a namespace (and not attached):
## [1] tidyselect_1.2.1 farver_2.1.2 libcoin_1.0-10
## [4] dplyr_1.1.4 matrixTests_0.2.3 bitops_1.0-8
## [7] fastmap_1.2.0 TH.data_1.1-2 pracma_2.4.4
## [10] MKdescr_0.9 digest_0.6.37 rpart_4.1.23
## [13] lifecycle_1.0.4 arrangements_1.1.9 survival_3.7-0
## [16] magrittr_2.0.3 compiler_4.4.1 rlang_1.1.4
## [19] sass_0.4.9 tools_4.4.1 utf8_1.2.4
## [22] yaml_2.3.10 knitr_1.48 labeling_0.4.3
## [25] multcomp_1.4-26 MKinfer_1.2 withr_3.0.1
## [28] purrr_1.0.2 nnet_7.3-19 grid_4.4.1
## [31] stats4_4.4.1 fansi_1.0.6 opdisDownsampling_1.0.1
## [34] jomo_2.7-6 caTools_1.18.2 colorspace_2.1-1
## [37] mice_3.16.0 ggplot2_3.5.1 scales_1.3.0
## [40] iterators_1.0.14 MASS_7.3-61 cli_3.6.3
## [43] mvtnorm_1.3-0 rmarkdown_2.28 generics_0.1.3
## [46] exactRankTests_0.8-35 twosamples_2.0.1 robustbase_0.99-4
## [49] minqa_1.2.8 DBI_1.2.3 cachem_1.1.0
## [52] modeltools_0.2-23 splines_4.4.1 parallel_4.4.1
## [55] matrixStats_1.3.0 mitools_2.4 vctrs_0.6.5
## [58] boot_1.3-31 glmnet_4.1-8 Matrix_1.7-0
## [61] sandwich_3.1-0 jsonlite_1.8.8 mitml_0.4-5
## [64] pbmcapply_1.5.1 foreach_1.5.2 hexbin_1.28.3
## [67] qqplotr_0.0.6 tidyr_1.3.1 jquerylib_0.1.4
## [70] glue_1.7.0 nloptr_2.1.1 pan_1.9
## [73] DEoptimR_1.1-3 codetools_0.2-20 shape_1.4.6.1
## [76] gtable_0.3.5 lme4_1.1-35.5 gmp_0.7-5
## [79] munsell_0.5.1 tibble_3.2.1 pillar_1.9.0
## [82] miceadds_3.17-44 htmltools_0.5.8.1 R6_2.5.1
## [85] doParallel_1.0.17 evaluate_0.24.0 lattice_0.22-6
## [88] highr_0.11 backports_1.5.0 broom_1.0.6
## [91] qqconf_1.3.2 bslib_0.8.0 Rcpp_1.0.13
## [94] nlme_3.1-166 xfun_0.47 coin_1.4-3
## [97] zoo_1.8-12 pkgconfig_2.0.3