Week 8 Exercises - Does Spending More Make More?
Two predictors, one budget, and a 30-year-old confound
About 45 minutes · Pairs or small groups · 🧰 R (tidyverse, rio, here, broom) or JAMOVI
Every step is given both ways.
- Part A: Follow along (~15 min): does a bigger budget buy a bigger box office?
- Part B: On your own (~20 min): add
year, watch the budget slope move, and explain why. - Part C: Together (~10 min): the question the data was collected to answer.
By the end you should be able to:
- Fit and interpret a model with two predictors
- Attach “holding ___ constant” to a coefficient and mean it
- Say why a coefficient changed when a second predictor entered
- Compute ΔR² and test it with a nested F
- Report a null result for a predictor that a lot of people care about
Set up (5 min)
Download the data into the
datafolder of your PSYC 640 R Project.New Quarto document,
Week 8 - Multiple Regression, saved asweek8_inclass.qmd.
library(tidyverse)
library(rio)
library(here)
library(broom)
films_raw <- import(here("data", "bechdel.csv"))
glimpse(films_raw)The raw dollar columns are in dollars, so every coefficient would come out in dollars and the output becomes unreadable. We will work in millions.
films <- films_raw %>%
mutate(gross_m = intgross_2013 / 1e6, # international gross, $M (2013 dollars)
budget_m = budget_2013 / 1e6, # budget, $M (2013 dollars)
bechdel = factor(binary, levels = c("fail", "pass"))) %>%
drop_na(gross_m, budget_m, year)
nrow(films)1,763 films survive, spanning 1970–2013. Mean budget ≈ $55.8M, mean gross ≈ $197.9M (SD ≈ 284).
If you got 1,774, your as.numeric() step did not run and your gross variable is still text.
- ☰ Menu → Open → Browse →
bechdel.csv - JAMOVI will import
intgross_2013as Nominal (text) because of the#N/Avalues. Fix it in two steps:- Double-click the
intgross_2013column header → change Measure type to Continuous. The#N/Acells become missing. - Data → Compute, new variable
gross_m, formula:intgross_2013 / 1000000
- Double-click the
- Data → Compute, new variable
budget_m, formula:budget_2013 / 1000000 - Confirm under Exploration → Descriptives that
gross_mhas N = 1763 andbudget_mhas a mean near 55.8.
All dollar figures below are in millions of 2013 dollars. Say so in your write-up; a coefficient without units is not a finding.
Part A — Follow along (15 min)
A1. Look before you model
films %>%
select(year, budget_m, gross_m) %>%
psych::describe(fast = TRUE)
films %>%
ggplot(aes(x = budget_m, y = gross_m)) +
geom_point(alpha = .3) +
geom_smooth(method = "lm", se = FALSE, color = "#B3261E") +
labs(x = "Budget ($M)", y = "International gross ($M)",
title = "Bigger budgets, bigger returns?") +
theme_bw()- Exploration → Descriptives:
year,budget_m,gross_minto Variables; check Mean, SD, Minimum, Maximum - Exploration → scatr → Scatterplot:
budget_mon X,gross_mon Y, Regression Line = Linear
Q1. Describe the cloud. Where do most films sit, and what does the handful of points in the upper right do to a regression line?
A2. One predictor
mod_budget <- lm(gross_m ~ budget_m, data = films)
summary(mod_budget)
#glance(mod_budget) %>% select(r.squared, adj.r.squared, sigma)Regression → Linear Regression: gross_m → Dependent Variable, budget_m → Covariates. Under Model Coefficients check Estimate and Standard error; under Model Fit check R², Adjusted R² and Overall model test (F test).
b0 = 27.47, b1 = 3.054, R² = .349, RSE = 229.2, F(1, 1761) = 945.85
Q2. Interpret budget_m in a sentence a studio executive would understand. Include the units.
Q3. The intercept is 27.47. What film does that describe, and is it a film that exists?
Q4. R² = .349 and RSE = 229. Put the RSE in plain language: when this model guesses a film’s gross, how far off is it typically? Compare that to the SD of gross_m (284).
Part B — On your own (20 min)
The data span 1970 to 2013. That is four decades of changing audiences, changing numbers of theaters, and changing release strategies — all inside one regression that pretends they are the same.
B1. Does year matter on its own?
mod_year <- lm(gross_m ~ year, data = films)
summary(mod_year)
#glance(mod_year) %>% select(r.squared, adj.r.squared)Q5. Year alone: R² = .019, b = −4.32. Write the interpretation. Does the sign surprise you? (Remember every dollar here is already inflation-adjusted to 2013.)
B2. Now both
mod_both <- lm(gross_m ~ budget_m + year, data = films)
summary(mod_both)
#glance(mod_both) %>% select(r.squared, adj.r.squared, sigma)Same Linear Regression panel — drag year into Covariates alongside budget_m. JAMOVI updates the coefficient table immediately.
| b | p | |
|---|---|---|
| intercept | 11654.52 | < .001 |
budget_m |
3.127 | < .001 |
year |
−5.808 | < .001 |
R² = .3829, adj. R² = .3822, RSE = 223.3
Q6. Interpret both coefficients, each with its holding constant clause.
Q7. The budget slope went up: 3.054 → 3.127. Most people expect a coefficient to shrink when you add a control. Use these three correlations to explain why this one grew:
Try to use the sjPlot library to make it look nice!
films %>% select(year, budget_m, gross_m) %>% cor() %>% round(3)Regression → Correlation Matrix: all three variables into the box.
year is positively related to budget (r = .08) and negatively related to gross (r = −.14). So part of what made the raw budget slope look smaller was that expensive films are disproportionately recent, and recent films gross less. Hold year still and the budget effect comes through a little more cleanly. This is the same machinery as Lab 8’s suppression, in a gentler form.
B3. Did year earn its place?
anova(mod_budget, mod_both)Use Model Builder: put budget_m in Block 1, click + Add New Block and put year in Block 2. Then open Model Comparisons — JAMOVI reports ΔR² and the F test for the added block directly.
Q8. Report ΔR² and the nested F in APA format. Then answer in one sentence: did adding year improve the model enough to keep it?
Q9. Adjusted R² also rose (.3491 → .3822). Why do we check adjusted R² here rather than just R²?
Q10. Use the model to predict the international gross of a $50M film released in 2013, and of a $50M film released in 1980.
predict(mod_both, newdata = tibble(budget_m = 50, year = c(2013, 1980)))Which prediction would you trust more, and why?
Part C — Together (10 min)
C1. The reason this dataset exists
The binary column records whether a film passes the Bechdel test: does it have at least two named women who talk to each other about something other than a man? A common industry claim is that films centered on women are a worse financial bet.
Start with the raw comparison:
films %>%
group_by(bechdel) %>%
summarise(n = n(),
mean_gross = mean(gross_m),
mean_budget = mean(budget_m))| n | mean gross | mean budget | |
|---|---|---|---|
| fail | 972 | 223.3 | 63.5 |
| pass | 791 | 166.6 | 46.4 |
Q11. Taken alone, films that pass gross about $57M less. Before you conclude anything — what else is different about those two groups in that table?
C2. Ask it properly
mod_bechdel <- lm(gross_m ~ budget_m + year + bechdel, data = films)
summary(mod_bechdel)
anova(mod_both, mod_bechdel)Drag bechdel into Factors (not Covariates — it is categorical). Under Reference Levels, confirm the reference is fail. Add it as Block 3 in Model Builder to get its ΔR².
bechdel (pass vs. fail): b = +5.96, SE = 10.88, t = 0.55, p = .584
ΔR² = .0001, F(1, 1759) = 0.30, p = .584
❓Questions for Part C
- The raw difference was −$57M. Controlling for budget and year it is +$6M, non-significant. Explain to a producer what happened — in words, not in regression vocabulary.
- Write the APA sentence reporting this null result. Then write the sentence you would put in the discussion section.
- Someone reads your output and says “so the Bechdel test doesn’t matter.” Give two different things your model cannot tell them.
- Films that pass have budgets averaging $46M vs $63M for films that fail. Your model treats that as a nuisance to control away. What if it is the actual finding?
“Control for the obvious confound” is not a technicality — it is sometimes the whole result. The raw gap was real and the adjusted gap is roughly zero, and which of those two numbers answers the question depends entirely on what question you asked. The model cannot tell you that part.
Exit ticket ✅
- In your own words: what does “holding X constant” let you compare?
- A colleague says “my R² went up, so the new predictor helped.” What do you ask them for?
- One thing that is still muddy → journal.