Today

  • Use lm() with two-group and three-group categorical predictors.
  • Interpret the reference group and dummy-coded coefficients.
  • Count dummy coefficients, beta coefficients, and total model parameters.
  • Calculate group means from coefficients, then use predict() as a check.
  • Read a coefficient t-test and an overall model F-test.

Complete the online lecture before the workshop and the Week 7 problem set afterwards.

From Continuous To Categorical Predictors

In Weeks 5–6, each continuous predictor entered as a single linear term added one slope coefficient. A categorical predictor can add more than one coefficient:

Predictor Coefficients added, excluding the intercept
Continuous age 1 slope
Medication group: 2 levels 1 group difference
Smoking group: 3 levels 2 group differences

One categorical predictor with G levels adds G − 1 coefficients. We still fit one intercept as well.

These are general linear models, whether predictors are continuous, categorical, or both.

Population Means In A Group Model

Two population means can be represented using one regression equation:

\[ \mu_i = \beta_0 + \beta_1 X_i. \]

  • For the reference group, \(X=0\): its mean is \(\beta_0\).
  • For the other group, \(X=1\): its mean is \(\beta_0+\beta_1\).
  • Therefore, \(\beta_1\) (by itself) is the other group’s mean minus the reference mean.

lm() estimates these population parameters from our sample.

Like the equal variance independent samples t-test, the linear model assumes a common residual SD, sigma, around the group means.

Start In RStudio

Open your module’s RStudio Project and check that workshop_data is inside it.

  1. Download week_07_workshop.R from NOW.
  2. Move it into your project folder using your file explorer.
  3. Open it in RStudio.

Wait for each exercise checkpoint. Run one line at a time and keep your coefficient output visible for the worked examples.

Demonstration Data

blomkvist <- read_csv("workshop_data/analysis_blomkvist.csv")
blomkvist <- drop_na(blomkvist, rt, meds_group)
count(blomkvist, meds_group)

meds_group already contains “medicated” and “not medicated”. We do not need to create a new grouping variable.

Do the medication groups differ in mean hand reaction time?

The prepared data are adapted from Blomkvist et al. (2017).

Exercise Checkpoint 1

Complete the data-loading steps and Part A1 with me.

m_lm <- lm(rt ~ meds_group, data = blomkvist)

The formula has the same structure as Week 5; the predictor now contains group labels.

Fit and print the model, save its summary, and print its coefficients. Wait for the slide “Count The Two-Group Model” before answering the counting questions. Keep the coefficient output visible.

Identify which coefficient is the reference mean and which is a difference.

How To Read A Categorical Coefficient Name

coef(m_lm)
            (Intercept) meds_groupnot medicated 
               738.8143               -157.4875 

A continuous coefficient usually uses its variable name, such as age. Here R joins the predictor name and the comparison level:

Part of the label Meaning
meds_group The predictor variable
not medicated The level compared with the reference group

Here the reference is medicated. This coefficient gives not medicated minus medicated, not the not-medicated mean on its own.

Two Groups: Read The Coefficients

coef(m_lm)
            (Intercept) meds_groupnot medicated 
               738.8143               -157.4875 
Coefficient Meaning Value (ms)
(Intercept) medicated mean 738.8143
meds_groupnot medicated not-medicated minus medicated mean -157.4875

Read the coefficient names to identify the reference mean and the other group’s difference.

Read The Dummy Code

With these text labels, R orders the levels alphabetically. The first level is the reference and the remaining level gets a binary indicator.

Medication group Not-medicated dummy Predicted mean
medicated 0 intercept
not medicated 1 intercept + group coefficient

“medicated” comes before “not medicated”, so it is coded 0; “not medicated” is coded 1.

Two levels give 2 - 1 = 1 dummy variable. In general, G levels give G - 1 dummy variables. R creates these codes inside lm().

Which Level Is The Reference?

A model predicts quiz score from study_mode, with two levels: classroom and online.

     (Intercept) study_modeonline 
              70               -8 
  • Which level is the reference group, whose predicted mean is the intercept?
  • How does the coefficient name help you identify it?
  • What does the slope coefficient -8 represent?

Discuss: What is the predicted mean quiz score for each group? No calculator needed.

Reference Level: Check Your Reasoning

  • classroom is the reference level: its dummy code is 0, so its predicted mean is 70.
  • study_modeonline joins the predictor study_mode and the comparison level online. It represents online minus classroom.
  • The dummy-coded slope is -8: the predicted online mean is 8 points lower.
Study mode Dummy code Predicted quiz score
classroom 0 70
online 1 70 + (-8) = 62

The intercept gives the reference mean; the other coefficient gives a difference, rather than the other group’s mean.

Count The Two-Group Model

Use rt ~ meds_group, our model with two medication levels. Answer the counting questions in Part A1; no new R commands are needed.

  1. How many predictor variables are in the model?
  2. How many dummy slope coefficients represent the two levels?
  3. Add the intercept: how many beta coefficients are there altogether?
  4. Add the shared residual SD, sigma: how many model parameters are there altogether?

Check the beta count against the names printed by coef(m_lm). Sigma is a parameter, but is reported separately from the beta coefficients.

Calculate The Two Group Means

coef(m_lm)
            (Intercept) meds_groupnot medicated 
               738.8143               -157.4875 

Here X = 0 for medicated and X = 1 for not medicated.

\[ \widehat{\mu}_i = \widehat{\beta}_0 + \widehat{\beta}_1 X_i. \]

Group Substitute the dummy code Predicted mean (ms)
medicated 738.8143 + (-157.4875) × 0 738.8143
not medicated 738.8143 + (-157.4875) × 1 581.3268

Check The Manual Calculation With predict()

new_meds <- tibble(
  meds_group = c("medicated", "not medicated")
)
predict(m_lm, newdata = new_meds)

Now that we have calculated the means by hand, use predict() to check them. tibble() supplies one row per group.

predict() uses the fitted model and returns one predicted mean per row. The column name and group labels must match the model.

predict() uses the fitted model directly. For the manual calculation, read and add the printed coefficient values.

Read The Group Test

Use the coefficient row for the group difference, not the intercept row.

m_lm_summary <- summary(m_lm)
m_lm_summary$coefficients
                         Estimate Std. Error   t value     Pr(>|t|)
(Intercept)              738.8143   21.95403 33.652780 4.444748e-77
meds_groupnot medicated -157.4875   28.50877 -5.524177 1.222335e-07

Find the meds_groupnot medicated row. Read its t value and Pr(>|t|) columns, as in Week 6.

The null hypothesis is that the population group difference is 0.

Same Group Comparison, Same Result

Compare with equal-variance t-test.

Quantity t.test(rt ~ meds_group, data = blomkvist, var.equal = TRUE) lm(rt ~ meds_group, data = blomkvist)
Subtraction order medicated minus not medicated not medicated minus medicated
Mean difference (ms) 157.4875 -157.4875
t-value 5.5242 -5.5242
Two-sided p-value 1.222e-07 1.222e-07

Opposite subtraction order: opposite signs, equal magnitudes and identical two-sided p-values.

Exercise Checkpoint 2

Complete Part A2.

Read the coefficient values for each named group, calculate its mean, check with predict(), then read the group t-statistic and p-value. Briefly compare with the provided equal-variance t-test.

Stop after Part A2.

Short Break

After the break, we will extend the same logic to three groups.

Three Groups Need Two Dummy Variables

Alphabetical order of the text levels: former smoker → non-smoker → smoker.

Three levels give 3 - 1 = 2 dummy variables.

Group Non-smoker dummy Smoker dummy Population mean
former smoker 0 0 \(\beta_0\)
non-smoker 1 0 \(\beta_0+\beta_1\)
smoker 0 1 \(\beta_0+\beta_2\)

The first level, “former smoker”, is the reference: both its codes are 0. Each other level has a 1 in its own column and a 0 in the other.

Fit The Three-Group Model

Start Part A3 with me: fit the model and read its coefficients.

m_smoker <- lm(rt ~ smoker, data = blomkvist_smoker)
coef(m_smoker)
     (Intercept) smokernon-smoker     smokersmoker 
       652.51316        -17.95079        -19.06444 
Coefficient Meaning (RT in ms)
(Intercept) former-smoker mean
smokernon-smoker non-smoker mean minus former-smoker mean
smokersmoker smoker mean minus former-smoker mean

The first smoker is the predictor name; the rest is the level. In smokersmoker, only the second “smoker” names the level.

Calculate The Three Group Means

coef(m_smoker)
     (Intercept) smokernon-smoker     smokersmoker 
       652.51316        -17.95079        -19.06444 
Calculation Predicted mean (ms)
A: 652.513158 + (-19.064440) 633.4487
B: 652.513158 652.5132
C: 652.513158 + (-17.950786) 634.5624

Match A, B and C to the groups: former smoker, non-smoker and smoker.

Which coefficient name tells you which calculation to use?

Count The Three-Group Model

Repeat the steps in Part A3 for rt ~ smoker, using its three levels and the coefficient names you just read.

  1. Count the predictor variables.
  2. Count the dummy slope coefficients for the group differences.
  3. Add the intercept to count all beta coefficients.
  4. Add the shared sigma to count all model parameters.

Compare with the two-group model: what increased, and what stayed the same?

K counts non-intercept beta coefficients. Use n − K − 1 for residual df; sigma is excluded from K.

From Week 6: Sum Sq To R-Squared

anova() now gives us the ESS and RSS supplied in Week 6.

anova(m_smoker)
Analysis of Variance Table

Response: rt
           Df      Sum Sq     Mean Sq F value  Pr(>F)
smoker      2   17793.332  8896.66595 0.24369 0.78391
Residuals 262 9565066.423 36507.88711                

Sum Sq: smoker = ESS (explained); Residuals = RSS (unexplained).

TSS = ESS + RSS, so R² = ESS / TSS.

Part A3: read the two Sum Sq values, calculate TSS and R-squared, then check against summary(m_smoker)$r.squared.

From Sum Sq To Mean Sq

Analysis of Variance Table

Response: rt
           Df      Sum Sq     Mean Sq F value  Pr(>F)
smoker      2   17793.332  8896.66595 0.24369 0.78391
Residuals 262 9565066.423 36507.88711                

\[ \text{Mean Sq} = \frac{\text{Sum Sq}}{\text{Df}}. \]

Part A3: divide each row’s Sum Sq by its own Df. Do your two results match the Mean Sq column?

These are explained and unexplained variation per degree of freedom. The divisions from Week 6’s F formula are already done for us.

The Overall F-Test

m_smoker_summary <- summary(m_smoker)
m_smoker_summary$fstatistic
 value  numdf  dendf 
0.2437      2    262 
anova(m_smoker)
Analysis of Variance Table

Response: rt
           Df      Sum Sq     Mean Sq F value  Pr(>F)
smoker      2   17793.332  8896.66595 0.24369 0.78391
Residuals 262 9565066.423 36507.88711                

Both outputs give the same overall F-statistic.

Sum Sq: smoker = ESS, Residuals = RSS; together they make TSS.

Null hypothesis: all three population means are equal.

Exercise Checkpoint 3

Analysis of Variance Table

Response: rt
           Df      Sum Sq     Mean Sq F value  Pr(>F)
smoker      2   17793.332  8896.66595 0.24369 0.78391
Residuals 262 9565066.423 36507.88711                

\[ F = \frac{\text{explained Mean Sq}}{\text{unexplained Mean Sq}}. \]

  • Part A3: calculate F from the smoker and Residuals Mean Sq values.
  • Calculate its p-value with pf(f_stat, df1, df2, lower.tail = FALSE), using the two Df entries.
  • Explain how the overall F-test differs from the non-smoker coefficient’s t-test.

Independent Practice

Complete Part B with the Chinese lexical-decision data.

  • Fit rt ~ accuracy_group and calculate both means from its coefficients.
  • Count its dummy slopes, add the intercept, then add sigma. Read the group t-statistic and p-value.
  • Then fit rt ~ list_group using all four prepared list groups.
  • Repeat the counting steps for four groups; calculate all four means and read the overall F-test.

After Part B, discuss your results. Complete the Week 7 problem set after the workshop for consolidation. The separate stretch task is optional.

Discuss Your Output

  • How do coefficient names reveal the reference group?
  • Why are there three group coefficients for four list groups?
  • How does an overall F-test differ from one coefficient’s t-test?

The Week 7 problem set asks for two-group predictions and a three-group overall test. Use the same logic even when the data set and labels change.

Optional Stretch Script

Only open week_07_stretch.R if the core exercise felt comfortable. It checks the overall F-test against an intercept-only model, then practises calculating F and its p-value for an age-group model. It is not required preparation for the exam.

After The Workshop

Recommended reading: Andrews (2021), Chapter 9, Normal Linear Models.

Complete the Week 7 problem set after this workshop. Calculate group means from the intercept and group differences; use predict() when a check is helpful. No downloaded dummy-coding function or extra prediction package is needed.

The first three questions use a two-group model. The remaining questions use three groups and ask for an overall test. Apply the same workflow to the new data and group labels.

Core R Functions

Function / syntax What it does
lm() / coef() fit a group model and extract coefficients
summary() print coefficient tests and overall model fit
tibble() / predict() specify groups and predict their means
t.test(..., var.equal = TRUE) run the matching equal-variance test
anova(model) show the overall group F-test
pf(..., lower.tail = FALSE) calculate the upper-tail F-test p-value
count() / summarise() check group sizes and means

Leave With

  • The intercept is the reference-group mean in a group-only model.
  • Each dummy coefficient is a difference from that mean.
  • A predictor with G groups needs G - 1 dummy coefficients.
  • A group-only normal model has G beta coefficients and one shared sigma.
  • Group predictions, coefficient tests, and overall tests answer different questions.

References

Andrews, M. (2021). Doing data science in R: An Introduction for Social Scientists. SAGE Publications Ltd.

Blomkvist, A. W., Eika, F., Rahbek, M. T., Eikhof, K. D., Hansen, M. D., Søndergaard, M., Ryg, J., Andersen, S., & Jørgensen, M. G. (2017). Reference data on reaction time and aging using the Nintendo Wii Balance Board: A cross-sectional study of 354 subjects from 20 to 99 years of age. PLoS One, 12(12), e0189598.