model.matrix expands a formula into the numeric columns that modeling functions use internally.

Program

Play the script to shift a numeric predictor and inspect the final design-row values.

dose_shift
model_matrix.R
Replay: real traced execution (multi-file project)
samples <- data.frame(group = factor(c("A", "B", "A")), dose = c(1, 2, 3))
dose_shift <- 0
samples$dose <- samples$dose + dose_shift
design <- model.matrix(~ group + dose, data = samples)
last <- paste(colnames(design), design[3, ], sep = "=", collapse = "; ")
cat(last, "\n", sep = "")
samples <- data.frame(group = factor(c("A", "B", "A")), dose = c(1, 2, 3))
dose_shift <- 1
samples$dose <- samples$dose + dose_shift
design <- model.matrix(~ group + dose, data = samples)
last <- paste(colnames(design), design[3, ], sep = "=", collapse = "; ")
cat(last, "\n", sep = "")
samples <- data.frame(group = factor(c("A", "B", "A")), dose = c(1, 2, 3))
dose_shift <- 2
samples$dose <- samples$dose + dose_shift
design <- model.matrix(~ group + dose, data = samples)
last <- paste(colnames(design), design[3, ], sep = "=", collapse = "; ")
cat(last, "\n", sep = "")
  1. samples ← 3 rows x 2 cols

    1samples <- data.frame(group = factor(c("A", "B", "A")), dose = c(1, 2, 3))2dose_shift <- 0
    values this step3 rows x 2 colssamples
  2. dose_shift ← 0

    1samples <- data.frame(group = factor(c("A", "B", "A")), dose = c(1, 2, 3))2dose_shift <- 03samples$dose <- samples$dose + dose_shift
    values this step0dose_shift
  3. samples$dose <- samples$dose + dose_shift

    2dose_shift <- 03samples$dose <- samples$dose + dose_shift4design <- model.matrix(~ group + dose, data = samples)
    values this step1, 2, 3samples$dose0dose_shift
  4. design ← 3 rows x 3 cols

    3samples$dose <- samples$dose + dose_shift4design <- model.matrix(~ group + dose, data = samples)5last <- paste(colnames(design), design[3, ], sep = "=", collapse = "; ")
    values this step3 rows x 3 colsdesign~ group + doseformula
  5. last ← (Intercept)=1; groupB=0; dose=3

    4design <- model.matrix(~ group + dose, data = samples)5last <- paste(colnames(design), design[3, ], sep = "=", collapse = "; ")6cat(last, "\n", sep = "")
    values this step(Intercept)=1; groupB=0; dose=3last1, 0, 3design[3, ]
  6. cat(last, " ", sep = "")

    5last <- paste(colnames(design), design[3, ], sep = "=", collapse = "; ")6cat(last, "\n", sep = "")
    output(Intercept)=1; groupB=0; dose=3
    values this step(Intercept)=1; groupB=0; dose=3last
  1. samples ← 3 rows x 2 cols

    1samples <- data.frame(group = factor(c("A", "B", "A")), dose = c(1, 2, 3))2dose_shift <- 1
    values this step3 rows x 2 colssamples
  2. dose_shift ← 1

    1samples <- data.frame(group = factor(c("A", "B", "A")), dose = c(1, 2, 3))2dose_shift <- 13samples$dose <- samples$dose + dose_shift
    values this step1dose_shift
  3. samples$dose ← 2, 3, 4

    2dose_shift <- 13samples$dose <- samples$dose + dose_shift4design <- model.matrix(~ group + dose, data = samples)
    values this step1, 2, 3 2, 3, 4samples$dose1dose_shift
  4. design ← 3 rows x 3 cols

    3samples$dose <- samples$dose + dose_shift4design <- model.matrix(~ group + dose, data = samples)5last <- paste(colnames(design), design[3, ], sep = "=", collapse = "; ")
    values this step3 rows x 3 colsdesign~ group + doseformula
  5. last ← (Intercept)=1; groupB=0; dose=4

    4design <- model.matrix(~ group + dose, data = samples)5last <- paste(colnames(design), design[3, ], sep = "=", collapse = "; ")6cat(last, "\n", sep = "")
    values this step(Intercept)=1; groupB=0; dose=4last1, 0, 4design[3, ]
  6. cat(last, " ", sep = "")

    5last <- paste(colnames(design), design[3, ], sep = "=", collapse = "; ")6cat(last, "\n", sep = "")
    output(Intercept)=1; groupB=0; dose=4
    values this step(Intercept)=1; groupB=0; dose=4last
  1. samples ← 3 rows x 2 cols

    1samples <- data.frame(group = factor(c("A", "B", "A")), dose = c(1, 2, 3))2dose_shift <- 2
    values this step3 rows x 2 colssamples
  2. dose_shift ← 2

    1samples <- data.frame(group = factor(c("A", "B", "A")), dose = c(1, 2, 3))2dose_shift <- 23samples$dose <- samples$dose + dose_shift
    values this step2dose_shift
  3. samples$dose ← 3, 4, 5

    2dose_shift <- 23samples$dose <- samples$dose + dose_shift4design <- model.matrix(~ group + dose, data = samples)
    values this step1, 2, 3 3, 4, 5samples$dose2dose_shift
  4. design ← 3 rows x 3 cols

    3samples$dose <- samples$dose + dose_shift4design <- model.matrix(~ group + dose, data = samples)5last <- paste(colnames(design), design[3, ], sep = "=", collapse = "; ")
    values this step3 rows x 3 colsdesign~ group + doseformula
  5. last ← (Intercept)=1; groupB=0; dose=5

    4design <- model.matrix(~ group + dose, data = samples)5last <- paste(colnames(design), design[3, ], sep = "=", collapse = "; ")6cat(last, "\n", sep = "")
    values this step(Intercept)=1; groupB=0; dose=5last1, 0, 5design[3, ]
  6. cat(last, " ", sep = "")

    5last <- paste(colnames(design), design[3, ], sep = "=", collapse = "; ")6cat(last, "\n", sep = "")
    output(Intercept)=1; groupB=0; dose=5
    values this step(Intercept)=1; groupB=0; dose=5last
model.matrix `model.matrix(~ group + dose, data)` creates columns from a formula.
intercept R includes an intercept column unless the formula removes it.
factor expansion A factor such as `group` becomes indicator columns like `groupB`.