library(tidyverse)
library(broom)
library(modelsummary)
library(patchwork)
library(flextable)
library(dagitty)
raw <- read_csv("data/morg-2014-emp.csv", show_col_types = FALSE)
cps <- raw |>
filter(
!is.na(earnwke), earnwke > 0,
!is.na(uhours), uhours > 0,
!is.na(occ2012), !is.na(grade92),
!is.na(age), !is.na(sex)
) |>
mutate(
wage = earnwke / uhours,
female = as.integer(sex == 2),
educ = grade92,
occ = factor(occ2012)
) |>
filter(wage > 0, wage < 500) |>
select(wage, female, age, educ, occ)Session 5: Exercise Solution
Advanced Data Science · Europa-Universität Flensburg
1 Task 1 — Exploring the gap
1a. Summary table:
cps |>
mutate(gender = if_else(female == 1, "Female", "Male")) |>
group_by(gender) |>
summarise(
N = n(),
`Median wage` = median(wage) |> round(2),
`Mean log(wage)` = mean(log(wage)) |> round(3),
`SD wage` = sd(wage) |> round(2)
) |>
flextable() |>
autofit() |>
theme_vanilla()gender | N | Median wage | Mean log(wage) | SD wage |
|---|---|---|---|---|
Female | 73,734 | 16.15 | 2.822 | 14.38 |
Male | 75,572 | 19.62 | 2.986 | 15.16 |
Answer (1a): The median hourly wage is approximately $19.62 for men and $16.15 for women — a raw gap of 17.7% in favour of men. In log-wage terms, this is 0.195 log points, which approximates the percentage difference for small gaps.
1b. Density plot:
cps |>
mutate(gender = if_else(female == 1, "Female", "Male")) |>
ggplot(aes(log(wage), fill = gender)) +
geom_density(alpha = 0.45, colour = NA) +
scale_fill_manual(values = c("Female" = "tomato", "Male" = "steelblue")) +
labs(
x = "log(hourly wage, USD)",
y = "Density",
fill = NULL,
title = "Wage distribution by gender",
subtitle = "CPS 2014"
) +
theme_minimal()Answer (1b): The female distribution is shifted to the left — women are concentrated at lower log wages — but the two distributions overlap substantially. The shape and spread are similar. This suggests the gap is primarily a difference in location (the mean/median), not a dramatic difference in spread. The overlap matters: there are many women who earn more than many men, which a single coefficient cannot capture.
2 Task 2 — The three-model progression
m1 <- lm(log(wage) ~ female, data = cps)
m2 <- lm(log(wage) ~ female + age + educ, data = cps)
m3 <- lm(log(wage) ~ female + age + educ + occ, data = cps)2a. Regression table:
modelsummary(
list(
"Model 1: Raw gap" = m1,
"Model 2: + Demographics" = m2,
"Model 3: + Occupation" = m3
),
coef_map = c(
"female" = "Female",
"age" = "Age",
"educ" = "Education (grade92)"
),
gof_omit = "AIC|BIC|Log|F|RMSE",
stars = TRUE,
notes = "Occupation dummies (Model 3) omitted from display."
)| Model 1: Raw gap | Model 2: + Demographics | Model 3: + Occupation | |
|---|---|---|---|
| + p < 0.1, * p < 0.05, ** p < 0.01, *** p < 0.001 | |||
| Occupation dummies (Model 3) omitted from display. | |||
| Female | -0.164*** | -0.212*** | -0.138*** |
| (0.003) | (0.003) | (0.003) | |
| Age | 0.012*** | 0.009*** | |
| (0.000) | (0.000) | ||
| Education (grade92) | 0.109*** | 0.060*** | |
| (0.001) | (0.001) | ||
| Num.Obs. | 149306 | 149306 | 149306 |
| R2 | 0.016 | 0.271 | 0.384 |
| R2 Adj. | 0.016 | 0.271 | 0.382 |
2b. Causal interpretation of each model:
Model 1: The coefficient of -0.164 says that female workers earn on average 16.4% less per hour in log terms than male workers. This is a descriptive statement — a conditional mean comparison. It makes no causal claim, because the raw gap reflects everything that varies with gender in this sample: differences in age, education, occupation, sector, and any direct pay discrimination. To interpret -0.164 as evidence of discrimination, we would need to rule out all of these alternative explanations, which we cannot do with this model.
Model 2: Adding age and education changes the estimated gap to -0.212 — which is larger in magnitude than the raw gap in Model 1. This is counterintuitive at first: we added controls, but the measured gap grew. The reason is that women in this sample are on average more educated than men. Education raises wages, so in the raw data women’s higher educational attainment was partially offsetting the gender pay gap. Once we hold education constant — comparing men and women at the same education level — that offsetting effect is removed and a larger underlying gap is revealed. This is confounding working in women’s favour in the raw data; controlling for it goes in the ‘widening’ direction. Age and education are plausible confounders (not mediators), so adding them is defensible — but this model still cannot claim to be causal because unobserved confounders (family background, employer practices, negotiation behaviour) remain.
Model 3: The female coefficient shrinks further to -0.138 when we add occupation. This model answers a narrower question: do women earn less than men within the same occupation, holding age and education constant? Whether this is the right question depends on whether occupation is a confounder or a mediator — which is the subject of Task 3. If occupational sorting is itself driven by gender discrimination (women are steered toward lower-paying occupations), then controlling for occupation removes part of the very effect we are trying to measure. Model 3 is not wrong — it just answers a different question than Model 1 or 2.
3 Task 3 — Causal reasoning
3a. Is occupation a confounder, mediator, or collider?
Occupation is a mediator for the question “does gender affect wages?”
- Does gender affect occupation? Yes. Occupational sorting by gender is well-documented: women are systematically under-represented in high-paying fields (technology, finance, senior management) and over-represented in lower-paying ones (education, care work, administrative roles). This sorting reflects a mix of preferences, socialization, hiring discrimination, and barriers to entry.
- Does occupation affect wages? Yes, directly — different occupations have different pay scales.
- Is there a direct effect of gender on wages not through occupation? Yes — within the same occupation, pay-setting practices can discriminate directly.
The causal structure is: gender → occupation → wage (mediation) AND gender → wage directly (discrimination in pay setting). Occupation sits on the causal path from gender to wage. It is not an independent cause of both — it is caused by gender and then causes wages.
3b. What happens when we control for occupation?
The correct answer is (b): the coefficient estimates a different, narrower quantity — the direct pay gap within occupations.
When we add occupation as a control, we block the mediated path (gender → occupation → wage) and estimate only the direct channel (gender → wage, net of occupational sorting). This is not a more precise estimate of total discrimination — it is an estimate of one component of it. If the research question is “is there discrimination in pay-setting within occupational categories?”, Model 3 is the right tool. If the question is “what is the total effect of gender on wages, including sorting?”, Model 3 gives the wrong answer.
3c. A genuine confounder:
Family background (parental education, household wealth, social networks) is a confounder not in this dataset. It affects wages (through connections, education quality, cultural capital) and is correlated with gender only weakly — but more importantly, it is correlated with both wage outcomes and the educational choices and occupational paths that men and women pursue.
A clearer example: sector of employment (private vs. public sector, unionised vs. non-union). Women are more likely to work in the public sector, where wages are more compressed. Public sector employment causes both lower average wages and is correlated with gender — it is not caused by gender discrimination, so it is a confounder, not a mediator.
Direction of bias: public sector → lower wages (negative effect on wages); female → more likely in public sector (positive correlation with female indicator). By the direction-of-bias rule: omitting sector overstates the male advantage — we attribute to gender what is partly a sector composition effect.
3d. DAG in dagitty and adjustment sets:
wage_dag <- dagitty("dag {
Gender -> Wage
Gender -> Occupation
Occupation -> Wage
}")
# Q1: adjustment set for the total effect of Gender on Wage
adjustmentSets(wage_dag, exposure = "Gender", outcome = "Wage") {}
# Q2: adjustment set for the causal effect of Occupation on Wage
adjustmentSets(wage_dag, exposure = "Occupation", outcome = "Wage"){ Gender }
Answer (3d):
Q1 returns an empty set. Given this DAG, no controls are needed to identify the total causal effect of gender on wages. There are no back-door paths from Gender to Wage: the only other path runs through Occupation (Gender → Occupation → Wage), which is a front-door mediated path, not a back-door confounding path. Controlling for anything here would either be redundant or harmful.
Q2 returns { Gender }. When Occupation is the exposure, Gender is now a common cause of both Occupation and Wage — it opens a back-door path (Occupation ← Gender → Wage) that must be blocked by controlling for Gender.
The adjustment set changed even though the DAG is identical, because the question changed. This confirms the verbal answer to Task 3a: occupation is a mediator for the gender-wage question, but gender is a confounder for the occupation-wage question. Confounder and mediator are not fixed properties of a variable — they depend on what you treat as the exposure.
4 Task 4 — Analytical narrative
Below is an example of how the analytical narrative could be structured.
4.1 The raw gap
The raw gender wage gap in the 2014 CPS is 16.4% (Model 1 coefficient: -0.164). This means female workers earn, on average, 16.4% less per hour than male workers on a log scale. This figure describes a real difference in the data, but it cannot be interpreted as evidence of discrimination. The gap reflects the combined effect of every way men and women differ in this sample: age, education, occupation, sector, and any direct pay discrimination. Distinguishing these mechanisms requires additional modelling.
4.2 Controlling for demographics
Adding age and education changes the estimated gap to -0.212 — larger in magnitude than the raw Model 1 estimate of -0.164. This is counterintuitive: adding controls made the gap grow rather than shrink. The reason is that women in this sample are on average more educated than men, and education is associated with higher wages. In the raw comparison, women’s educational advantage was partially masking the gender pay gap. Holding education constant removes that offsetting effect, and the full gap is revealed. Age and education are plausible confounders (not mediators): they affect wages independently and are distributed differently across genders. But even Model 2 cannot claim to be causal — unobserved confounders remain.
4.3 The occupation question
Key caveat: Adding occupation (Model 3, coefficient = -0.138) does not produce a more accurate estimate of the gender wage gap. Occupation is a mediator — if gender discrimination causes women to be sorted into lower-paying occupations, controlling for occupation blocks that causal channel and produces a narrower estimate that reflects only within-occupation pay differences. Model 3 answers a different question than Model 1 or 2, not a more correct one.
Model 3 tells us the pay gap between men and women in the same occupation, holding age and education constant. This is a meaningful quantity if the research question is specifically about pay discrimination within job categories. But if we want to measure total wage inequality by gender — including the occupational sorting component — Model 3 understates it.
5 Bonus — Alternative DAG scenario
B1. DAG for advertising and sales:
The causal structure involves three main variables:
- Product quality → advertising spend (better products justify larger marketing budgets)
- Product quality → sales revenue (better products sell more)
- Advertising spend → sales revenue (advertising may drive awareness and purchases)
Product quality is a confounder — it causes both advertising spend and sales revenue without being caused by either. Without controlling for it, the observed positive relationship between advertising and sales overstates the causal effect of advertising, because high-advertising firms also tend to have better products.
B2. Product quality is a confounder. It is a common cause of both advertising spend (the treatment) and sales revenue (the outcome), and it is not caused by either. Omitting it from a regression of sales on advertising would produce an upward-biased estimate of the advertising effect.
B3. Manager experience is also a confounder, not a mediator. The analyst’s description is correct: experienced managers spend more on advertising AND work at firms with better products. Both paths lead to higher sales. Including it as a control is appropriate — it closes a back-door path from manager quality to both advertising and sales. This is a good idea, as long as we do not think manager experience is caused by advertising decisions (which seems implausible).
B4. To establish that advertising causes sales, we would need an experiment: randomly assign advertising budgets to otherwise comparable firms (or time periods for the same firm) and measure the effect on sales. In practice, firms often use A/B tests for digital advertising — showing different ad levels to randomly selected customer segments — which provides clean identification of the causal effect within those segments.