Hair Color Example

Assume following laws:

  • Income is log-normally distributed
  • Brown hair causes a 10% increase to income
  • A college degree produces a 20% income boost

Other assumptions (laws):

  • 20% of population have naturally brown hair
  • 30% of population have college degrees
  • 40% of folks with neither natural brown hair nor college degrees will dye hair brown
Hair Color Data Generation
set.seed(1337)
N <- 1337
brown_hair <- sample(c(1,0), N, replace = TRUE, prob = c(0.20, 0.80))
college <- sample(c(1,0), N, replace = TRUE, prob = c(0.30, 0.70))
dye_jobs <- brown_hair
for(i in 1:N){
  if(brown_hair[i] == 0){
    if(college[i] == 0){
      if(runif(1) <= 0.40){
        dye_jobs[i] <- 1
      }
    }
  }
}
brown_hair <- dye_jobs
log_income <- 0.1*brown_hair + 0.2*college + rnorm(N, 5, 1.5)
hair_df <- data.frame(brown_hair, college, log_income)
hair_df$brown_hair <- factor(hair_df$brown_hair)
hair_df$college    <- factor(hair_df$college)

college_df <- hair_df |> filter(college == 1)

brown_haired <- hair_df |> filter(brown_hair == 1) |> pull(log_income)
other_haired <- hair_df |> filter(brown_hair == 0) |> pull(log_income)
log_treatment <- mean(brown_haired) - mean(other_haired)
treatment_eff <- exp(log_treatment)

So far, we observe that brown-haired people make 0.9 as much as people with other hair colors.

  • but the stated law was “Brown hair causes a 10% increase to income”

brown_haired <- college_df |> filter(brown_hair == 1) |> pull(log_income)
other_haired <- college_df |> filter(brown_hair == 0) |> pull(log_income)
log_treatment <- mean(brown_haired) - mean(other_haired)
treatment_eff <- exp(log_treatment)

So far, we observe that brown-haired people make 1.04 as much as people with other hair colors.

  • but the stated law was “Brown hair causes a 10% increase to income”

Two core ideas

  • Variation - How can we find variation we need and focus on it?
  • Identification - How can we use DGP to be sure we’re teasing out the right variation?