Part 2: In-Class Lab Activity (Pair-Based)

EPI 553 — Tests of Hypotheses Lab Due: End of class


Instructions

This lab uses a Driver-Navigator pair programming approach. You will work with a partner, taking turns in two roles:

  • Driver: Types the code and writes answers in the .Rmd file
  • Navigator: Reviews the code, checks logic, suggests improvements, and helps interpret results

Round 1 (Tasks 1–3): Student A is the Driver, Student B is the Navigator. Round 2 (Tasks 4–6): Student B is the Driver, Student A is the Navigator.

Switch roles after completing Task 3. Both partners should understand all tasks — the Navigator should actively participate by checking the work, asking questions, and discussing interpretations.

Submission: Each pair submits one knitted HTML file with both partners’ names. Upload to Brightspace by end of class.


Data for the Lab

Use the same BRFSS 2020 dataset from the guided practice.

# Load packages and data
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.5.2
## Warning: package 'ggplot2' was built under R version 4.5.2
## Warning: package 'tibble' was built under R version 4.5.2
## Warning: package 'tidyr' was built under R version 4.5.2
## Warning: package 'readr' was built under R version 4.5.2
## Warning: package 'purrr' was built under R version 4.5.2
## Warning: package 'dplyr' was built under R version 4.5.2
## Warning: package 'stringr' was built under R version 4.5.2
## Warning: package 'forcats' was built under R version 4.5.2
## Warning: package 'lubridate' was built under R version 4.5.2
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.0     ✔ readr     2.2.0
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.2     ✔ tibble    3.3.1
## ✔ lubridate 1.9.5     ✔ tidyr     1.3.2
## ✔ purrr     1.2.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(broom)
## Warning: package 'broom' was built under R version 4.5.2
library(knitr)
## Warning: package 'knitr' was built under R version 4.5.2
library(kableExtra)
## Warning: package 'kableExtra' was built under R version 4.5.2
## 
## Attaching package: 'kableExtra'
## 
## The following object is masked from 'package:dplyr':
## 
##     group_rows
library(car)
## Warning: package 'car' was built under R version 4.5.2
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.5.2
## 
## Attaching package: 'car'
## 
## The following object is masked from 'package:dplyr':
## 
##     recode
## 
## The following object is masked from 'package:purrr':
## 
##     some
library(gtsummary)
## Warning: package 'gtsummary' was built under R version 4.5.2
brfss_mlr <- readRDS(
  "C:/Users/abbym/OneDrive/Desktop/STATS553/R Materials/epi553/scripts/brfss_mlr_2020.rds"
)

Grading Rubric

Task Description Points
Task 1 Fitting Models and ANOVA Tables 15
Task 2 Type I vs. Type III Sums of Squares 15
Task 3 Partial F-Tests for Individual Variables 20
Switch roles
Task 4 T-Tests and the F-Test Equivalence 15
Task 5 Chunk Test (Testing Groups of Variables) 20
Task 6 Synthesis and Interpretation 15
Total 100

Round 1: Student A Drives, Student B Navigates


Task 1: Fitting Models and ANOVA Tables (15 points)

Use tidy() with conf.int = TRUE to display the coefficients. Report the fitted equation with rounded coefficients.

model_a <- lm(menthlth_days ~ physhlth_days + sleep_hrs + age,
             data = brfss_mlr)

tidy(model_a, conf.int = TRUE) %>%
  mutate(across(where(is.numeric), ~ round(., 4))) %>%
  kable(
    caption = "Table 1. Model A Coefficients",
    col.names = c("Term", "Estimate", "Std. Error", "t-statistic", "p-value", "95% CI Lower", "95% CI Upper")
  ) %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table 1. Model A Coefficients
Term Estimate Std. Error t-statistic p-value 95% CI Lower 95% CI Upper
(Intercept) 10.6684 0.6102 17.4844 0 9.4722 11.8646
physhlth_days 0.3182 0.0131 24.2179 0 0.2924 0.3439
sleep_hrs -0.5063 0.0760 -6.6630 0 -0.6553 -0.3573
age -0.0800 0.0059 -13.4532 0 -0.0916 -0.0683
# Calculate Type I SS
anova_type1 <- anova(model_a)

anova_type1 %>%
  as.data.frame() %>%
  rownames_to_column("Source") %>%
  mutate(across(where(is.numeric), ~ round(., 2))) %>%
  kable(
    caption = "Table 2. Type I (Sequential) Sums of Squares — anova(), Model A",
    col.names = c("Source", "df", "Sum of Sq", "Mean Sq", "F value", "p-value")
  ) %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
  footnote(general = "Variables are tested in the order they appear in the model formula.")
Table 2. Type I (Sequential) Sums of Squares — anova(), Model A
Source df Sum of Sq Mean Sq F value p-value
physhlth_days 1 29474.75 29474.75 576.00 0
sleep_hrs 1 3323.04 3323.04 64.94 0
age 1 9261.47 9261.47 180.99 0
Residuals 4996 255652.08 51.17 NA NA
Note:
Variables are tested in the order they appear in the model formula.
# Calculate model SS
type1_ss <- anova_type1$`Sum Sq`
ssr_full <- sum(type1_ss[1:3])  # Model SS (sum of all predictor Type I SS)
sse_full <- type1_ss[4]          # Residual SS

cat("SSR (Model):", round(ssr_full, 2), "\n")
## SSR (Model): 42059.26
# Calculate Type III SS
# Type III using car::Anova()
anova_type3 <- Anova(model_a, type = "III")

# Side-by-side comparison
comparison <- tibble(
  Variable = c("physhlth_days", "sleep_hrs", "age"),
  `Type I SS` = round(anova_type1$`Sum Sq`[1:3], 1),
  `Type III SS` = round(anova_type3$`Sum Sq`[2:4], 1)
)

comparison %>%
  kable(caption = "Table 3. Type I vs. Type III Sums of Squares, Model A") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
  footnote(general = "Type I SS depends on variable entry order; Type III SS does not. The last variable (age) has identical values.")
Table 3. Type I vs. Type III Sums of Squares, Model A
Variable Type I SS Type III SS
physhlth_days 29474.7 30012.3
sleep_hrs 3323.0 2271.8
age 9261.5 9261.5
Note:
Type I SS depends on variable entry order; Type III SS does not. The last variable (age) has identical values.

1a. (5 pts) Fit the following model:

\[\text{menthlth\_days} = \beta_0 + \beta_1 \cdot \text{physhlth\_days} + \beta_2 \cdot \text{sleep\_hrs} + \beta_3 \cdot \text{age} + \varepsilon\] \[\text{menthlth\_days} = 10.6684 + 0.3182\text{physhlth\_days} + -0.5063 \text{sleep\_hrs} + -0.0800 \text{age} + \varepsilon\] 1b. (5 pts) Use anova() on this model to obtain the Type I (sequential) sums of squares. Present the ANOVA table and verify that the sum of all predictor Type I SS equals the model SSR. Show this calculation explicitly. 29474.75 + 3323.04 + 9261.47= 42,059.26 1c. (5 pts) Use car::Anova() with type = "III" on the same model to obtain the Type III sums of squares. Compare the Type I and Type III SS for each variable. Which variable’s SS is the same in both tables? Why? Age is the same in both tables, because type I is based on variables that come after the variable, and since age is the last variable in the model, it is the same for both type I and type III. —

Task 2: Type I vs. Type III Sums of Squares (15 points)

# Model B
model_b <- lm(menthlth_days ~ age + sleep_hrs + physhlth_days,
             data = brfss_mlr)
# Fitted Model
tidy(model_b, conf.int = TRUE) %>%
  mutate(across(where(is.numeric), ~ round(., 4))) %>%
  kable(
    caption = "Table 4. Model B Coefficients",
    col.names = c("Term", "Estimate", "Std. Error", "t-statistic", "p-value", "95% CI Lower", "95% CI Upper")
  ) %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table 4. Model B Coefficients
Term Estimate Std. Error t-statistic p-value 95% CI Lower 95% CI Upper
(Intercept) 10.6684 0.6102 17.4844 0 9.4722 11.8646
age -0.0800 0.0059 -13.4532 0 -0.0916 -0.0683
sleep_hrs -0.5063 0.0760 -6.6630 0 -0.6553 -0.3573
physhlth_days 0.3182 0.0131 24.2179 0 0.2924 0.3439
# Type I
anova_type1 <- anova(model_b)

anova_type1 %>%
  as.data.frame() %>%
  rownames_to_column("Source") %>%
  mutate(across(where(is.numeric), ~ round(., 2))) %>%
  kable(
    caption = "Table 5. Type I (Sequential) Sums of Squares — anova(), Model B",
    col.names = c("Source", "df", "Sum of Sq", "Mean Sq", "F value", "p-value")
  ) %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
  footnote(general = "Variables are tested in the order they appear in the model formula.")
Table 5. Type I (Sequential) Sums of Squares — anova(), Model B
Source df Sum of Sq Mean Sq F value p-value
age 1 7249.10 7249.10 141.66 0
sleep_hrs 1 4797.91 4797.91 93.76 0
physhlth_days 1 30012.26 30012.26 586.51 0
Residuals 4996 255652.08 51.17 NA NA
Note:
Variables are tested in the order they appear in the model formula.
car::Anova(model_b, type = "III")
## Anova Table (Type III tests)
## 
## Response: menthlth_days
##               Sum Sq   Df F value    Pr(>F)    
## (Intercept)    15643    1 305.706 < 2.2e-16 ***
## age             9261    1 180.989 < 2.2e-16 ***
## sleep_hrs       2272    1  44.396 2.972e-11 ***
## physhlth_days  30012    1 586.505 < 2.2e-16 ***
## Residuals     255652 4996                      
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Calculate Type III SS
# Type III using car::Anova()
anova_type3 <- Anova(model_b, type = "III")

# Side-by-side comparison
comparison <- tibble(
  Variable = c("age", "sleep_hrs", "physhlth_days"),
  `Type I SS` = round(anova_type1$`Sum Sq`[1:3], 1),
  `Type III SS` = round(anova_type3$`Sum Sq`[2:4], 1)
)

comparison %>%
  kable(caption = "Table 6. Type I vs. Type III Sums of Squares, Model B") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
  footnote(general = "Type I SS depends on variable entry order; Type III SS does not. The last variable (physhlth_days) has identical values.")
Table 6. Type I vs. Type III Sums of Squares, Model B
Variable Type I SS Type III SS
age 7249.1 9261.5
sleep_hrs 4797.9 2271.8
physhlth_days 30012.3 30012.3
Note:
Type I SS depends on variable entry order; Type III SS does not. The last variable (physhlth_days) has identical values.

2a. (5 pts) Fit the same model from Task 1 but reverse the variable order:

\[\text{menthlth\_days} = \beta_0 + \beta_1 \cdot \text{age} + \beta_2 \cdot \text{sleep\_hrs} + \beta_3 \cdot \text{physhlth\_days} + \varepsilon\] \[\text{menthlth\_days} = 10.6684 + -0.0800 \text{age} + -0.5063 \text{sleep\_hrs} + 0.3182 \text{physhlth\_days} + \varepsilon\] Run anova() on this model and compare the Type I SS to what you obtained in Task 1b. Which values changed and which stayed the same? None of the values stayed the same. 2b. (5 pts) Run car::Anova(type = "III") on this reordered model. Did the Type III SS change compared to Task 1c? Explain why or why not. The type III SS did not change compared to task 1c, because the order of the variables does not matter when evaluating type III error. 2c. (5 pts) In 2–3 sentences, explain when an epidemiologist should prefer Type III SS over Type I SS. Give a concrete example from public health research where the choice matters. An epidemiologist should prefer Type III over Type I SS when they are wondering what an additional variable will do to a whole model, rather than its specific additional impact it has on the model. For example, an epidemiologist might want to use type III over type I when they are looking to see the whole impact of a variable on the model. For example, they may want to use type III for something like seeing if age will impact calcium intake and bone mineral density, as it shouldn’t matter the order it goes in. If it were something that required more of a sequential order, like the impact of smoking, then age, on lung cancer outcome, they may want to use Type I.

Task 3: Partial F-Tests for Individual Variables (20 points)

# Partial F-test
model_full <- lm(menthlth_days ~ physhlth_days + sleep_hrs + age,
             data = brfss_mlr)
model_reduced <- lm(menthlth_days ~ physhlth_days + sleep_hrs,
             data = brfss_mlr)

anova(model_reduced, model_full)
## Analysis of Variance Table
## 
## Model 1: menthlth_days ~ physhlth_days + sleep_hrs
## Model 2: menthlth_days ~ physhlth_days + sleep_hrs + age
##   Res.Df    RSS Df Sum of Sq      F    Pr(>F)    
## 1   4997 264914                                  
## 2   4996 255652  1    9261.5 180.99 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Manual Calculation
ssr_full    <- sum(anova(model_full)$`Sum Sq`[1:3])
ssr_reduced <- sum(anova(model_reduced)$`Sum Sq`[1:2])
mse_full    <- anova(model_full)$`Mean Sq`[4]  # MSE of full model

F_stat <- (ssr_full - ssr_reduced) / 1 / mse_full

cat("SSR(full):", round(ssr_full, 2), "\n")
## SSR(full): 42059.26
cat("SSR(reduced):", round(ssr_reduced, 2), "\n")
## SSR(reduced): 32797.79
cat("SS(Age | others):", round(ssr_full - ssr_reduced, 2), "\n")
## SS(Age | others): 9261.47
cat("MSE(full):", round(mse_full, 2), "\n")
## MSE(full): 51.17
cat("F-statistic:", round(F_stat, 4), "\n")
## F-statistic: 180.9894
cat("Critical value F(1, 4996, 0.95):", round(qf(0.95, 1, 4996), 4), "\n")
## Critical value F(1, 4996, 0.95): 3.8433
cat("p-value:", format.pval(pf(F_stat, 1, 4996, lower.tail = FALSE)), "\n")
## p-value: < 2.22e-16

3a. (10 pts) Conduct a partial F-test to determine whether age adds significantly to the prediction of mental health days, given that physhlth_days and sleep_hrs are already in the model. Do this by:

  1. Fitting a reduced model (without age)
  2. Fitting the full model (with age)
  3. Using anova(reduced, full) to compare them

State the null hypothesis, report the F-statistic and p-value, and state your conclusion at \(\alpha = 0.05\). The null hypothesis is that age does not add statistically significant information to the model. The F-statistic is 180.99 and the p-value is < 2.2e-16, which means you reject the null hypothesis, meaning age does add statistically significant information to the model. 3b. (10 pts) Now verify your result from 3a manually. Using the anova() output from the full model (Task 1b), identify \(SS(\text{age} \mid \text{physhlth\_days}, \text{sleep\_hrs})\) from the Type I table. Compute the F-statistic as:

\[F = \frac{SS(\text{age} \mid \text{physhlth\_days}, \text{sleep\_hrs}) / 1}{MSE(\text{full model})}\] F= [(29474.75+3323.04+9261.47)/1]/ Compare to the critical value \(F_{1, n-p-1, 0.95}\). Does your manual calculation agree with the anova() comparison from 3a? Yes, it does agree with the anova comparison from 3a. They are both 180.99. —

Round 2: Student B Drives, Student A Navigates

⟳ Switch roles now!


Task 4: T-Tests and the F-Test Equivalence (15 points)

# Get t-statistics from summary()
t_stats <- tidy(model_full) %>%
  filter(term != "(Intercept)") %>%
  select(term, t_stat = statistic, t_pvalue = p.value)

# Get F-statistics from Type III
f_stats <- Anova(model_full, type = "III") %>%
  as.data.frame() %>%
  rownames_to_column("term") %>%
  filter(!term %in% c("(Intercept)", "Residuals")) %>%
  select(term, f_stat = `F value`, f_pvalue = `Pr(>F)`)

# Compare
left_join(t_stats, f_stats, by = "term") %>%
  mutate(
    `t²` = round(t_stat^2, 4),
    f_stat = round(f_stat, 4),
    `t² = F?` = ifelse(abs(t_stat^2 - f_stat) < 0.001, "✓", "✗"),
    t_pvalue = round(t_pvalue, 6),
    f_pvalue = round(f_pvalue, 6),
    `p-values equal?` = ifelse(abs(t_pvalue - f_pvalue) < 0.0001, "✓", "✗")
  ) %>%
  select(term, t_stat = t_stat, `t²`, `F (Type III)` = f_stat, `t² = F?`,
         `p (t-test)` = t_pvalue, `p (F-test)` = f_pvalue, `p-values equal?`) %>%
  mutate(t_stat = round(t_stat, 4)) %>%
  kable(caption = "Table 7. Equivalence of T-Tests and Type III Partial F-Tests") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table 7. Equivalence of T-Tests and Type III Partial F-Tests
term t_stat F (Type III) t² = F? p (t-test) p (F-test) p-values equal?
physhlth_days 24.2179 586.5051 586.5051 0 0
sleep_hrs -6.6630 44.3961 44.3961 0 0
age -13.4532 180.9894 180.9894 0 0
summary(model_full)
## 
## Call:
## lm(formula = menthlth_days ~ physhlth_days + sleep_hrs + age, 
##     data = brfss_mlr)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -15.1227  -3.4457  -1.8464   0.0493  30.3922 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   10.668370   0.610164  17.484  < 2e-16 ***
## physhlth_days  0.318159   0.013137  24.218  < 2e-16 ***
## sleep_hrs     -0.506317   0.075989  -6.663 2.97e-11 ***
## age           -0.079966   0.005944 -13.453  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 7.153 on 4996 degrees of freedom
## Multiple R-squared:  0.1413, Adjusted R-squared:  0.1408 
## F-statistic:   274 on 3 and 4996 DF,  p-value: < 2.2e-16

4a. (5 pts) Using the full model from Task 1 (menthlth_days ~ physhlth_days + sleep_hrs + age), run summary() and extract the t-statistics and p-values for each coefficient.

4b. (5 pts) For each predictor, compute \(t^2\) and compare it to the Type III F-statistic from Task 1c. Create a table showing the t-statistic, \(t^2\), the Type III F-statistic, and both p-values. Are they equivalent? Yes, they are equivalent. 4c. (5 pts) In your own words, explain why the t-test and the Type III partial F-test give the same result. What is the fundamental relationship between the t-distribution and the F-distribution that makes this true? The t-test and F-test give the same result because the null hypotheses are being tested while considering all other variables. Neither of them are order-dependent, either. They are testing the same things, while using the same statistical contributions. —

Task 5: Chunk Test — Testing Groups of Variables (20 points)

# Test group
# Reduced model: 
model_partial <- lm(menthlth_days ~ physhlth_days + sleep_hrs + age, data = brfss_mlr)

# Full model: health behaviors + demographics
m_full <- lm(menthlth_days ~ physhlth_days + sleep_hrs + age + income_cat + sex + exercise,
             data = brfss_mlr)

tidy(m_full, conf.int = TRUE) %>%
  mutate(across(where(is.numeric), ~ round(., 4))) %>%
  kable(
    caption = "Table 1. Model A Coefficients",
    col.names = c("Term", "Estimate", "Std. Error", "t-statistic", "p-value", "95% CI Lower", "95% CI Upper")
  ) %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table 1. Model A Coefficients
Term Estimate Std. Error t-statistic p-value 95% CI Lower 95% CI Upper
(Intercept) 12.4755 0.7170 17.4006 0.0000 11.0699 13.8810
physhlth_days 0.2917 0.0136 21.4779 0.0000 0.2650 0.3183
sleep_hrs -0.5092 0.0753 -6.7574 0.0000 -0.6569 -0.3614
age -0.0823 0.0059 -13.8724 0.0000 -0.0939 -0.0707
income_cat -0.3213 0.0520 -6.1778 0.0000 -0.4233 -0.2194
sexFemale 1.2451 0.2023 6.1535 0.0000 0.8484 1.6417
exerciseYes -0.3427 0.2531 -1.3537 0.1759 -0.8389 0.1536
# Chunk test
anova(model_partial, m_full) %>%
  as.data.frame() %>%
  rownames_to_column("Model") %>%
  mutate(
    Model = c("Reduced (physhlth + sleep + age only)", "Full (+ demographics)"),
    across(where(is.numeric), ~ round(., 4))
  ) %>%
  kable(
    caption = "Table 8. Chunk Test: Do demographic variables collectively add to the model?",
    col.names = c("Model", "Res. df", "RSS", "df", "Sum of Sq", "F", "p-value")
  ) %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table 8. Chunk Test: Do demographic variables collectively add to the model?
Model Res. df RSS df Sum of Sq F p-value
Reduced (physhlth + sleep + age only) 4996 255652.1 NA NA NA NA
Full (+ demographics) 4993 250992.8 3 4659.276 30.8957 0
# Manual Computation
ssr_full    <- sum(anova(m_full)$`Sum Sq`[1:6])
ssr_reduced <- sum(anova(model_partial)$`Sum Sq`[1:3])
mse_full    <- anova(m_full)$`Mean Sq`[7]
df_diff     <- 4  # 4 additional variables

F_chunk <- ((ssr_full - ssr_reduced) / df_diff) / mse_full

cat("SSR(full):", round(ssr_full, 2), "\n")
## SSR(full): 46718.54
cat("SSR(reduced):", round(ssr_reduced, 2), "\n")
## SSR(reduced): 42059.26
cat("Difference:", round(ssr_full - ssr_reduced, 2), "\n")
## Difference: 4659.28
cat("df (number of added variables):", df_diff, "\n")
## df (number of added variables): 4
cat("MSE(full):", round(mse_full, 2), "\n")
## MSE(full): 50.27
cat("F-statistic:", round(F_chunk, 4), "\n")
## F-statistic: 23.1717
cat("Critical value F(4, 4993, 0.95):", round(qf(0.95, df_diff, 4993), 4), "\n")
## Critical value F(4, 4993, 0.95): 2.3737
cat("p-value:", format.pval(pf(F_chunk, df_diff, 4993, lower.tail = FALSE)), "\n")
## p-value: < 2.22e-16

5a. (10 pts) Now consider the full 6-predictor model:

\[\text{menthlth\_days} = \beta_0 + \beta_1 \cdot \text{physhlth\_days} + \beta_2 \cdot \text{sleep\_hrs} + \beta_3 \cdot \text{age} + \beta_4 \cdot \text{income\_cat} + \beta_5 \cdot \text{sex} + \beta_6 \cdot \text{exercise} + \varepsilon\]

Test whether income_cat, sex, and exercise — as a group — significantly add to the prediction of mental health days, given that physhlth_days, sleep_hrs, and age are already in the model.

State the null hypothesis (in both words and mathematical notation), conduct the test, and state your conclusion. Null Hypothesis:H0:βincome=βsex=βexercise=0; The group adds nothing statistically significant to the model. Alternative Hypothesis: H1:βincome=βsex=βexercise does not equal 0; The group improves the prediction ability of the model. 5b. (5 pts) Compute the chunk test F-statistic manually using:

\[F = \frac{\{SSR(\text{full}) - SSR(\text{reduced})\} / (df_{\text{full}} - df_{\text{reduced}})}{MSE(\text{full})}\]

Show all intermediate values. Does your manual computation match the anova() result?

5c. (5 pts) Note that exercise was not individually significant in the Type III table, yet it is part of a group that is collectively significant. In 2–3 sentences, explain how this is possible and what it means for model building in epidemiology. It is possible for something to not be statistically significant individually, but as a part of a group it is. This is because combined with the other variables, it can help to explain the model, but alone, it doesn’t contribute much. This means that even though something may not be individually important, it should be looked at as a group with other variables when building models in epidemiology. —

Task 6: Synthesis and Interpretation (15 points)

6a. (5 pts) Based on the full model, which predictors are statistically significant at \(\alpha = 0.05\)? List them and briefly state the direction of each association (positive or negative). The predictors that are statistically significant are physical health days, which have a positive association, hours of sleep, which has a negative association, age , which has a negative association, income category which has a negative association, and sex, which has a positive association with being female. 6b. (5 pts) A colleague argues: “We should drop exercise from the model because it’s not significant.” Do you agree? Write a 2–3 sentence response explaining your reasoning. Consider the chunk test results and epidemiologic rationale. I don’t agree, because it was shown that will the group, it did have an impact on the model and helped to make the whole model a better predictor of bad mental health days. Even though it is not individually significant, it still plays a role in increasing the understanding of bad mental health days in the entire model. 6c. (5 pts) Write a 3–4 sentence summary of the hypothesis testing results for a non-statistical audience (e.g., a public health program manager). Your summary should convey which factors were identified as independently associated with mental health days and which were not, without using jargon like “p-value,” “F-test,” or “sums of squares.” The number of bad physical health days, hours of sleep, age, income category, and sex were determined to be the most important factors to consider when predicting how many bad mental health days a person will have in a month. Exercise was determined to not be as important when predicting how many bad mental health days a person will have in a month. This was shown through a series of tests that determined if the combination of variables/individual variables were helpful in creating a model that could predict the number of bad mental health days a person will have in a month. ### Task 7: Reflection (Not Graded, strongly recommended) In 2–3 sentences, reflect on the process of working with a partner in this lab. What did you find helpful about the Driver-Navigator approach? How did it affect your understanding of the material? I think it is nice to work with a partner, as we can build on each other’s strengths in order to develop both of our understandings of the material. I think it was a bit hard to do the driver-navigator approach when we have to turn in separate documents and have to both have the code for everything. I think it is easier to work with a partner on these activities in the sense that we both do the code individually and then check over our work and answers together, as you can still increase your understanding of the material and get help where you need. —

End of Lab Activity