# Dose-Proportionality

### Details and examples of other methods are accessible via the menu bar on top of the page and the online manual of all functions.

    library(PowerTOST) # attach the library

# Defaults

Parameter | Argument | Purpose | Default
--- | --- | --- | ---
\(\small{\alpha}\) | `alpha` | Nominal level of the test | `0.05`
CV | `CV` | CV | none
doses | `doses` | Vector of doses | see examples
\(\small{\pi}\) | `targetpower` | Minimum desired power | `0.80`
\(\small{\beta_0}\) | `beta0` | ‘True’ or assumed slope of the power model | see below
\(\small{\theta_1}\) | `theta1` | Lower limit for the ratio of dose normalized means Rdmn | see below
\(\small{\theta_2}\) | `theta2` | Upper limit for the ratio of dose normalized means Rdmn | see below
design | `design` | Planned design | `"crossover"`
dm | `dm` | Design matrix | `NULL`
CVb | `CVb` | Coefficient of variation of the between-subject variability | –
print | `print` | Show information in the console? | `TRUE`
details | `details` | Show details of the sample size search? | `FALSE`
imax | `imax` | Maximum number of iterations | `100`

Arguments `targetpower`, `theta1`, `theta2`, and `CV` have to be given as fractions, not in percent.
The CV is generally the within- (intra-) subject coefficient of variation. Only for `design = "parallel"` it is the total (a.k.a. pooled) CV. The between- (intra-) subject coefficient of variation CVb is only necessary if `design = "IBD"` (if missing, it will be set to `2*CV`).

The ‘true’ or assumed slope of the power model \(\small{\beta_0}\) defaults to `1+log(0.95)/log(rd)`, where `rd` is the ratio of the highest/lowest dose.

Supported designs are `"crossover"` (default; Latin Squares), `"parallel"`, and `"IBD"` (incomplete block design). Note that when `"crossover"` is chosen, instead of Latin Squares any Williams’ design could be used as well (identical degrees of freedom result in the same sample size).

With `sampleN.dp(..., details = FALSE, print = FALSE)` results are provided as a data frame 1 with ten (`design = "crossover"`) or eleven (`design = "parallel"` or `design = "IBD"`) columns: `Design`, `alpha`, `CV`, (`CVb`,) `doses`, `beta0`, `theta1`, `theta2`, `Sample size`, `Achieved power`, and `Target power`. To access e.g., the sample size use `sampleN.dp[["Sample size"]]`.

The estimated sample size gives always the total number of subjects (not subject/sequence in crossovers or subjects/group in a parallel design – like in some other software packages).

# Examples

Estimate the sample size for a modified Fibonacci dose-escalation study, lowest dose 10, three levels. Assumed CV 0.20 and \(\small{\beta_0}\) slightly higher than 1. Defaults employed.

    mod.fibo <- function(lowest, levels) {
      # modified Fibonacci dose-escalation
      fib      <- c(2, 1 + 2/3, 1.5, 1 + 1/3)
      doses    <- numeric(levels)
      doses[1] <- lowest
      level    <- 2
      repeat {
        if (level <= 4) {
          doses[level] <- doses[level-1] * fib[level-1]
        } else {  # ratio 1.33 for all higher doses
          doses[level] <- doses[level-1] * fib[4]
        }
        level <- level + 1
        if (level > levels) {
          break
        }
      }
      return(signif(doses, 3))
    }
    lowest <- 10
    levels <- 3
    doses  <- mod.fibo(lowest, levels)
    sampleN.dp(CV = 0.20, doses = doses, beta0 = 1.02)
    #
    # ++++ Dose proportionality study, power model ++++
    #             Sample size estimation
    # -------------------------------------------------
    # Study design: crossover (3x3 Latin square)
    # alpha = 0.05, target power = 0.8
    # Equivalence margins of R(dnm) = 0.8 ... 1.25
    # Doses = 10 20 33.3
    # True slope = 1.02, CV = 0.2
    # Slope acceptance range = 0.81451 ... 1.1855
    #
    # Sample size (total)
    #  n     power
    # 15   0.808127

As above but with an additional level.

    levels <- 4
    doses  <- mod.fibo(lowest, levels)
    x <- sampleN.dp(CV = 0.20, doses = doses, beta0 = 1.02) # we need the data.frame later
    #
    # ++++ Dose proportionality study, power model ++++
    #             Sample size estimation
    # -------------------------------------------------
    # Study design: crossover (4x4 Latin square)
    # alpha = 0.05, target power = 0.8
    # Equivalence margins of R(dnm) = 0.8 ... 1.25
    # Doses = 10 20 33.3 50
    # True slope = 1.02, CV = 0.2
    # Slope acceptance range = 0.86135 ... 1.1386
    #
    # Sample size (total)
    #  n     power
    # 16   0.867441

Note that with the wider dose range the acceptance range narrows.

Explore the impact of dropouts.

    res <- data.frame(n = seq(x[["Sample size"]], 12, -1), power = NA)
    for (i in 1:nrow(res)) {
      res$power[i] <- signif(suppressMessages(
                               power.dp(CV = 0.20, doses = doses,
                                        beta0 = 1.02, n = res$n[i])), 5)
    }
    res <- res[res$power >= 0.80, ]
    print(res, row.names = FALSE)
    #   n   power
    #  16 0.86744
    #  15 0.82914
    #  14 0.81935
    #  13 0.81516

As usual nothing to worry about.

Rather extreme: Five levels and we desire only three periods. Hence, we opt for an incomplete block design. The design matrix of a balanced minimal repeated measurements design is obtained by the function `balmin.RMD()` of package `crossdes`.

    levels <- 5
    doses  <- mod.fibo(lowest, levels)
    per    <- 3
    block  <- levels*(levels-1)/(per-1)
    dm     <- crossdes::balmin.RMD(levels, block, per)
    x      <- sampleN.dp(CV = 0.20, doses = doses, beta0 = 1.02,
                         design = "IBD", dm = dm)
    #
    # ++++ Dose proportionality study, power model ++++
    #             Sample size estimation
    # -------------------------------------------------
    # Study design: IBD (5x10x3)
    # alpha = 0.05, target power = 0.8
    # Equivalence margins of R(dnm) = 0.8 ... 1.25
    # Doses = 10 20 33.3 50 66.7
    # True slope = 1.02, CV = 0.2, CVb = 0.4
    # Slope acceptance range = 0.88241 ... 1.1176
    #
    # Sample size (total)
    #  n     power
    # 30   0.898758

The IBD comes with a price since we need at least two blocks.

    res <- data.frame(n = seq(x[["Sample size"]], nrow(dm), -1),
                      power = NA)
    for (i in 1:nrow(res)) {
      res$power[i] <- signif(suppressMessages(
                               power.dp(CV = 0.20, doses = doses,
                                        beta0 = 1.02, design = "IBD",
                                        dm = dm, n = res$n[i])), 5)
    }
    res <- res[res$power >= 0.80, ]
    print(res, row.names = FALSE)
    #   n   power
    #  30 0.89876
    #  29 0.89196
    #  28 0.87939
    #  27 0.87201
    #  26 0.85793
    #  25 0.83587
    #  24 0.82470
    #  23 0.80405

Again, we don’t have to worry about dropouts.

For a wide dose range the acceptance range narrows and becomes increasingly difficult to meet.

    doses  <- 2^(seq(0, 8, 2))
    levels <- length(doses)
    sampleN.dp(CV = 0.30, doses = doses, beta0 = 1.02,
               design = "crossover")
    #
    # ++++ Dose proportionality study, power model ++++
    #             Sample size estimation
    # -------------------------------------------------
    # Study design: crossover (5x5 Latin square)
    # alpha = 0.05, target power = 0.8
    # Equivalence margins of R(dnm) = 0.8 ... 1.25
    # Doses = 1 4 16 64 256
    # True slope = 1.02, CV = 0.3
    # Slope acceptance range = 0.95976 ... 1.0402
    #
    # Sample size (total)
    #  n     power
    # 70   0.809991

In an exploratory setting more liberal limits could be specified (only one has to be specified; the other is calculated as the reciprocal of it).

    sampleN.dp(CV = 0.30, doses = doses, beta0 = 1.02,
               design = "crossover", theta1 = 0.75)
    #
    # ++++ Dose proportionality study, power model ++++
    #             Sample size estimation
    # -------------------------------------------------
    # Study design: crossover (5x5 Latin square)
    # alpha = 0.05, target power = 0.8
    # Equivalence margins of R(dnm) = 0.75 ... 1.333333
    # Doses = 1 4 16 64 256
    # True slope = 1.02, CV = 0.3
    # Slope acceptance range = 0.94812 ... 1.0519
    #
    # Sample size (total)
    #  n     power
    # 30   0.828246

Hummel et al. 2 proposed even more liberal \(\small{\theta_{1},\theta_{2}}\) of {0.50, 2.0}.

# Cave!

There is no guarantee that a desired incomplete block design (for given dose levels and number of periods) can be constructed. If you provide your own design matrix (in the argument `dm`) it is not assessed for meaningfulness.

# Author

Detlew Labes

# License

#### GPL-3 2025-09-17 Helmut Schütz

1. R Documentation. Data Frames. 2022-02-08. R-manual.↩︎

2. Hummel J, McKendrick S, Brindley C, French R. Exploratory assessment of dose proportionality: review of current approaches and proposal for a practical criterion. Pharm. Stat. 2009; 8(1): 38–49. doi:10.1002/pst.326.↩︎