Exam Guide Solution Question 1 1. dat <- mroz colSums(is.na(dat[, c("hours", "wage")])) ## hours ## 0 wage 325 The missing values are not necessarily due to data errors. In particular, women who are not participating in the labour force may not have an observed wage because they are not working. 2. ggplot(dat, aes(x = hours)) + geom_histogram() + labs(title = "Distribution of Hours Worked", x = "Hours worked", y = "Count") ## ‘stat_bin()‘ using ‘bins = 30‘. Pick better value ‘binwidth‘. 1 Distribution of Hours Worked 300 Count 200 100 0 0 1000 2000 3000 4000 5000 Hours worked The distribution is highly skewed and contains a large mass at zero because many women do not participate in the labour force. The majority are around a standard full-time work schedule (40*50=2000). Some very large values appear a little unusual, but they could plausibly reflect individuals working extremely long hours. Therefore, it is difficult to justify removing observations solely based on visual inspection. 3. ggplot(dat, aes(x = huswage, y = wage)) + geom_point() + labs(title = "Scatter Plot of Husband's Wage and Wage", x = "Husband's Wage", y = "Wage") ## Warning: Removed 325 rows containing missing values or values outside the scale range ## (‘geom_point()‘). 2 Scatter Plot of Husband's Wage and Wage 25 20 Wage 15 10 5 0 0 10 20 30 Husband's Wage The raw scatter plot is difficult to interpret because there are many overlapping observations. binsreg(y = dat$wage, x = dat$huswage) 3 40 dat$wage 5 4 3 0 10 20 dat$huswage ## Call: binsreg ## ## Binscatter Plot ## Bin/Degree selection method (binsmethod) = IMSE direct plug-in (select # of bins) ## Placement (binspos) = Quantile-spaced ## Derivative (deriv) = 0 ## ## Group (by) = Full Sample ## Sample size (n) = 428 ## # of distinct values (Ndist) = 401 ## # of clusters (Nclust) = NA ## dots, degree (p) = 0 ## dots, smoothness (s) = 0 ## # of bins (nbins) = 10 From the binscatter, it is easier to see a positive relationship. Part 4 reg_huswage <- feols(data = dat, hours ~ huswage, vcov = "hetero") summary(reg_huswage) 4 ## OLS estimation, Dep. Var.: hours ## Observations: 753 ## Standard-errors: Heteroskedasticity-robust ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 892.5182 58.43901 15.27264 < 2.2e-16 *** ## huswage -20.3072 5.89784 -3.44315 0.00060684 *** ## --## Signif. codes: 0 ’***’ 0.001 ’**’ 0.01 ’*’ 0.05 ’.’ 0.1 ’ ’ 1 ## RMSE: 866.5 Adj. R2: 0.008403 The intercept is 893, representing the predicted number of annual hours worked when the husband’s hourly wage is zero (i.e. they do not work). The coefficient on huswage is -20. This means that a one dollar increase in the husband’s hourly wage is associated with wives working about 20 fewer hours per year on average. The relationship is negative: married women tend to work fewer hours when their husbands earn higher wages. This is consistent with the idea that higher household income may reduce the wife’s labour supply, but this simple regression should not be interpreted causally. Part 5 The estimate from Part 4 may suffer from omitted variable bias if educ is related both to the husband’s wage and to the wife’s hours worked. For example, more educated women may tend to have higher-earning husbands. At the same time, education may increase women’s own labour market opportunities and therefore increase their labour supply. If education is omitted, the coefficient on huswage may partly capture differences in education rather than only the relationship between husbands’ wages and wives’ hours worked. Therefore, not controlling for education could positively bias the estimated relationship between huswage and hours. Part 6 reg_huswage_educ <- feols(data = dat, hours ~ huswage + educ, vcov = "hetero") summary(reg_huswage_educ) ## OLS estimation, Dep. Var.: hours ## Observations: 753 ## Standard-errors: Heteroskedasticity-robust ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 271.5826 159.72247 1.70034 8.9481e-02 . ## huswage -28.8693 6.22317 -4.63900 4.1307e-06 *** ## educ 55.7506 13.52526 4.12196 4.1758e-05 *** ## --## Signif. codes: 0 ’***’ 0.001 ’**’ 0.01 ’*’ 0.05 ’.’ 0.1 ’ ’ 1 ## RMSE: 857.9 Adj. R2: 0.026692 After controlling for education, the coefficient on huswage is -29. This means that, holding education fixed, a one dollar increase in the husband’s hourly wage is associated with wives working 29 fewer hours per year. The interpretation has changed relative to Part 4. The coefficient is no longer just the unconditional relationship between husbands’ wages and wives’ hours worked. It is now the relationship conditional on wives having the same level of education. 5 In this case, the coefficient is even more negative, so the basic conclusion is still that higher husbands’ wages are associated with lower wives’ labour supply but even more so now. Part 7 dat <- dat %>% mutate(youngkids = ifelse(kidslt6 > 0, 1, 0)) reg_interaction <- feols(data = dat, hours ~ huswage + educ + youngkids + huswage:youngkids, vcov = "hetero") summary(reg_interaction) ## OLS estimation, Dep. Var.: hours ## Observations: 753 ## Standard-errors: Heteroskedasticity-robust ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 258.81267 158.90578 1.628718 1.0379e-01 ## huswage -26.90084 6.76561 -3.976114 7.6848e-05 *** ## educ 63.70396 13.12041 4.855334 1.4638e-06 *** ## youngkids -442.33909 129.42863 -3.417629 6.6586e-04 *** ## huswage:youngkids -8.79580 11.52198 -0.763393 4.4547e-01 ## --## Signif. codes: 0 ’***’ 0.001 ’**’ 0.01 ’*’ 0.05 ’.’ 0.1 ’ ’ 1 ## RMSE: 833.8 Adj. R2: 0.078103 For women without young children, the effect of huswage on hours is given by the coefficient on huswage, -26.9. For women with young children, the effect is the sum of the coefficient on huswage and the interaction coefficient, (-26.9 - 8.8 = -35.7). Thus, for women with young children, a one dollar increase in the husband’s hourly wage is associated with about 35.7 additional annual hours worked. For women without young children, the corresponding effect is about 26.9 hours. Part 8 youngkids would be a mediator if husbands’ wages affected whether the household has young children, and this in turn affected wives’ hours worked. In that case, part of the effect of huswage on hours would operate through the presence of young children. reg_mediator <- feols(data = dat, hours ~ educ + huswage + youngkids, vcov = "hetero") summary(reg_mediator) ## OLS estimation, Dep. Var.: hours ## Observations: 753 ## Standard-errors: Heteroskedasticity-robust ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 274.8705 154.96937 1.77371 7.6518e-02 . 6 ## educ 63.3471 13.08888 4.83976 1.5791e-06 *** ## huswage -28.4799 5.93349 -4.79986 1.9171e-06 *** ## youngkids -509.8797 66.78329 -7.63484 6.8998e-14 *** ## --## Signif. codes: 0 ’***’ 0.001 ’**’ 0.01 ’*’ 0.05 ’.’ 0.1 ’ ’ 1 ## RMSE: 833.9 Adj. R2: 0.079058 In the model without youngkids, the coefficient on huswage is -28.9. After adding youngkids, the coefficient is -28.5. The coefficient changes only modestly. Therefore, if youngkids were considered a potential mediator, it does not appear to be a very important mechanism for the relationship between husbands’ wages and wives’ hours worked. Part 9 dat <- dat %>% mutate(lhuswage = log(huswage)) reg_log_huswage <- feols(data = dat, hours ~ lhuswage + educ + youngkids, vcov = "hetero") summary(reg_log_huswage) ## OLS estimation, Dep. Var.: hours ## Observations: 753 ## Standard-errors: Heteroskedasticity-robust ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 358.8141 163.1034 2.19992 2.8117e-02 * ## lhuswage -108.6494 51.7974 -2.09758 3.6277e-02 * ## educ 55.6455 13.1756 4.22337 2.7030e-05 *** ## youngkids -510.6521 67.3640 -7.58049 1.0193e-13 *** ## --## Signif. codes: 0 ’***’ 0.001 ’**’ 0.01 ’*’ 0.05 ’.’ 0.1 ’ ’ 1 ## RMSE: 839.7 Adj. R2: 0.06636 The coefficient on lhuswage is -108. Since the independent variable is in logs and the dependent variable is in levels, a 1 percent increase in the husband’s wage is associated with approximately -108/100=1.08 additional annual hours worked. r2(reg_mediator, type = "r2") ## r2 ## 0.08273216 r2(reg_log_huswage, type = "r2") ## r2 ## 0.07008427 The model with the larger R2 , the level-level regression, fits the sample slightly better. Yes, it is possible to compare R2 values here because the dependent variable is the same in both models. 7 Question 2 Part 1 dat <- dat %>% mutate(age2 = (age - mean(age))ˆ2) reg_lpm <- feols(data = dat, inlf ~ age + age2 + educ + exper + kidslt6 + huswage, vcov = "hetero") summary(reg_lpm) ## OLS estimation, Dep. Var.: inlf ## Observations: 753 ## Standard-errors: Heteroskedasticity-robust ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 0.776447 0.133505 5.81587 8.9454e-09 *** ## age -0.018300 0.002169 -8.43819 < 2.2e-16 *** ## age2 -0.000322 0.000249 -1.29551 1.9554e-01 ## educ 0.038206 0.007156 5.33890 1.2423e-07 *** ## exper 0.022856 0.002008 11.38292 < 2.2e-16 *** ## kidslt6 -0.267166 0.031576 -8.46096 < 2.2e-16 *** ## huswage -0.007691 0.004059 -1.89470 5.8519e-02 . ## --## Signif. codes: 0 ’***’ 0.001 ’**’ 0.01 ’*’ 0.05 ’.’ 0.1 ’ ’ 1 ## RMSE: 0.428015 Adj. R2: 0.247235 It may be appropriate to include a squared effect of age because the relationship between age and labour force participation may be nonlinear. For example, participation may rise with age at younger ages but fall later in life. The coefficient on age is negative and indicates that for someone who is average age, getting one year older is associated with decreasing the probability of being in the labour force by 1.8 percentage points. Part 2 If huswage contains classical measurement error, the estimated effect of huswage on inlf will usually be biased toward zero. This is called attenuation bias. Intuitively, classical measurement error adds noise to the regressor. This makes it harder for the regression to detect the true relationship, so the estimated coefficient is smaller in absolute value than it would be if huswage were measured without error. Part 3 dat <- dat %>% mutate(phat_lpm = predict(reg_lpm, newdata = dat)) min(dat$phat_lpm) ## [1] -0.2603922 8 max(dat$phat_lpm) ## [1] 1.121379 The minimum predicted probability from the LPM is -0.26, and the maximum predicted probability is 1.12. These values are outside the interval from zero to one. This does not make sense if we interpret them literally as probabilities, but it is a known limitation of the linear probability model. The LPM is linear and therefore does not force fitted values to lie between zero and one. Part 4 reg_probit <- feglm(data = dat, inlf ~ age + age2 + educ + exper + kidslt6 + huswage, family = binomial(link = "probit")) summary(reg_probit) ## GLM estimation, family = binomial(link = "probit"), Dep. Var.: inlf ## Observations: 753 ## Standard-errors: IID ## Estimate Std. Error z value Pr(>|z|) ## (Intercept) 0.792408 0.438530 1.80696 7.0768e-02 . ## age -0.057456 0.007882 -7.28919 3.1183e-13 *** ## age2 -0.001053 0.000852 -1.23585 2.1651e-01 ## educ 0.125949 0.024831 5.07223 3.9317e-07 *** ## exper 0.071720 0.007532 9.52143 < 2.2e-16 *** ## kidslt6 -0.845201 0.118972 -7.10419 1.2103e-12 *** ## huswage -0.023772 0.012644 -1.88017 6.0085e-02 . ## --## Signif. codes: 0 ’***’ 0.001 ’**’ 0.01 ’*’ 0.05 ’.’ 0.1 ’ ’ 1 ## Log-Likelihood: -406.9 Adj. Pseudo R2: 0.198092 ## BIC: 860.1 Squared Cor.: 0.258922 avg_slopes(reg_probit) ## ## Term Estimate Std. Error z Pr(>|z|) S 2.5 % 97.5 % ## age -0.017572 0.00216 -8.15 <0.001 51.3 -0.021798 -0.013345 ## age2 -0.000322 0.00026 -1.24 0.2152 2.2 -0.000831 0.000187 ## educ 0.038519 0.00723 5.33 <0.001 23.3 0.024354 0.052685 ## exper 0.021934 0.00188 11.67 <0.001 102.1 0.018250 0.025619 ## huswage -0.007270 0.00384 -1.89 0.0584 4.1 -0.014799 0.000258 ## kidslt6 -0.258492 0.03272 -7.90 <0.001 48.4 -0.322619 -0.194365 ## ## Type: response ## Comparison: dY/dX The average marginal effect of educ is 0.04. This means that one additional year of education is associated with an increase in the probability of labour force participation of 4 percentage points, holding the other variables fixed. 9 dat <- dat %>% mutate(phat_probit = predict(reg_probit, newdata = dat, type = "response")) Part 5 dat <- dat %>% mutate(pred_lpm = ifelse(phat_lpm >= 0.5, 1, 0), pred_probit = ifelse(phat_probit >= 0.5, 1, 0)) mean(dat$pred_lpm == dat$inlf) ## [1] 0.7343958 mean(dat$pred_probit == dat$inlf) ## [1] 0.7343958 mean(dat$inlf) ## [1] 0.5683931 The LPM hit ratio is and the probit hit ratio are 0.73, and the naive hit ratio is 0.57. Both the LPM and probit models improve on the naive model. The LPM and probit have the same hit ratios so neither dominates the other, but we can also check the Brier score: mean((dat$phat_lpm - dat$inlf)ˆ2) ## [1] 0.1831966 mean((dat$phat_probit - dat$inlf)ˆ2) ## [1] 0.1818039 Now we see that the probit has a slightly lower Brier score, so it is the preferred method. Question 3 Part 1 ggplot(dat, aes(x = RainMM, y = Visits)) + geom_point(alpha = 0.5) + geom_smooth(method = "lm", se = FALSE, colour = "firebrick") + labs(x = "Daily rainfall (mm)", y = "Daily gym check-ins", title = "Gym visits vs. rainfall") + theme_minimal() 10 ## ‘geom_smooth()‘ using formula = ’y ~ x’ Daily gym check−ins Gym visits vs. rainfall 1000 500 0 10 20 Daily rainfall (mm) cor(dat$RainMM, dat$Visits) ## [1] 0.05844299 The scatter shows essentially no clear relationship — the cloud of points is roughly flat and the correlation is tiny (~0.06). At most one might argue for a weak positive association. Crucially, no causal conclusion can be drawn from this plot. It is a purely bivariate correlation and rainfall is not randomly assigned. Confounders can drive both variables simultaneously — for example, day of week and seasonality affect both attendance and weather patterns. The omitted-variable problem and the descriptive nature of a scatter mean we cannot infer causality. Part 2 dat <- dat %>% mutate(L1_Visits = lag(Visits, n = 1), L1_RainMM = lag(RainMM, n = 1), DoW = as.factor(wday(Date))) datTrain <- dat[1:500, ] datTest <- dat[501:nrow(dat), ] nrow(datTrain); nrow(datTest) 11 ## [1] 500 ## [1] 231 The model forecasts gym visits one day ahead. A forecast for day t is made at the end of day t − 1, so every regressor must be observable at that point. • RainMM: Today’s rainfall is not known the day before. We therefore use the one-period lag L1_RainMM (yesterday’s rainfall), which is already observed. • Promo: Promotions are decided and announced in advance by the gym. Whether a promotion runs on day t is already known the day before, so contemporaneous Promo can be used directly without lagging. Note that row 1 of the training set has NA lags and is dropped automatically by feols, so models trained on datTrain use 499 observations. Part 3 m3 <- feols(Visits ~ L1_Visits + L1_RainMM + Promo, data = datTrain, vcov = vcov_NW(time = "Date")) ## NOTE: 1 observation removed because of NA values (RHS: 1). summary(m3) ## OLS estimation, Dep. Var.: Visits ## Observations: 499 ## Standard-errors: Newey-West (L=20) ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 8.253125 5.290187 1.56008 1.1938e-01 ## L1_Visits 0.982026 0.007944 123.61694 < 2.2e-16 *** ## L1_RainMM -1.856102 0.397867 -4.66514 3.9684e-06 *** ## Promo 51.017902 4.739265 10.76494 < 2.2e-16 *** ## --## Signif. codes: 0 ’***’ 0.001 ’**’ 0.01 ’*’ 0.05 ’.’ 0.1 ’ ’ 1 ## RMSE: 39.4 Adj. R2: 0.974604 pred3 <- predict(m3, newdata = datTest) mse3 <- mean((datTest$Visits - pred3)ˆ2) mse3 ## [1] 1542.539 The estimated coefficient on L1_Visits is approximately 0.98, indicating strong day-to-day persistence in gym attendance. L1_RainMM is approximately -1.9 (more rain yesterday is associated with slightly fewer visits today), and Promo is approximately +51 (a promotion adds around 51 check-ins). Newey-West standard errors are used because time-series residuals are typically serially correlated (and possibly heteroskedastic). Newey-West gives HAC-valid (heteroskedasticity and autocorrelation consistent) inference in this setting. The out-of-sample MSE for this model is approximately 1543. 12 Part 4 m4 <- feols(Visits ~ L1_Visits + L1_RainMM + Promo + DoW, data = datTrain, vcov = vcov_NW(time = "Date")) ## NOTE: 1 observation removed because of NA values (RHS: 1). summary(m4) ## OLS estimation, Dep. Var.: Visits ## Observations: 499 ## Standard-errors: Newey-West (L=9) ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) -33.595934 6.122883 -5.48695 6.5197e-08 *** ## L1_Visits 0.987225 0.007054 139.94345 < 2.2e-16 *** ## L1_RainMM -1.802309 0.276616 -6.51556 1.7757e-10 *** ## Promo 49.350781 2.876018 17.15941 < 2.2e-16 *** ## DoW2 83.299655 5.455722 15.26831 < 2.2e-16 *** ## DoW3 61.760564 4.461940 13.84164 < 2.2e-16 *** ## DoW4 50.488806 4.496109 11.22945 < 2.2e-16 *** ## DoW5 37.408751 4.625969 8.08668 4.7004e-15 *** ## DoW6 21.878252 4.346724 5.03327 6.7479e-07 *** ## DoW7 11.659714 4.582552 2.54437 1.1248e-02 * ## --## Signif. codes: 0 ’***’ 0.001 ’**’ 0.01 ’*’ 0.05 ’.’ 0.1 ’ ’ 1 ## RMSE: 28.5 Adj. R2: 0.986526 pred4 <- predict(m4, newdata = datTest) mse4 <- mean((datTest$Visits - pred4)ˆ2) c(MSE_no_DoW = mse3, MSE_with_DoW = mse4, improvement_pct = 100 * (mse3 - mse4) / mse3) ## ## MSE_no_DoW 1542.53942 MSE_with_DoW improvement_pct 852.46227 44.73644 Adding the day-of-week factor cuts the out-of-sample MSE from approximately 1543 to approximately 853, an improvement of around 45%. The preferred model is the one with the day-of-week dummies: gym attendance has a strong weekly cycle that the lagged visits variable alone cannot fully capture. The model is judged on out-of-sample performance, so the gain is genuine and not merely in-sample overfitting. It is also worth noting that the coefficients on the other regressors are largely unchanged by the inclusion of the day-of-week factor. Part 5 A time series has a unit root if it is non-stationary of the random-walk type. In an AR(1) model, Visitst = ρ · Visitst−1 + ut , a unit root means ρ = 1: shocks are permanent (they never die out), the series has no tendency to revert to a fixed mean, and its variance grows without bound over time. The estimated persistence of approximately 0.98 is close to 1, which may suggest a unit root. This is problematic for several reasons: 13 • Spurious regression: two unrelated unit-root series can appear highly significantly related (high R2 , large t-statistics) purely by chance. • Invalid inference: OLS t- and F -statistics no longer follow their standard distributions under a unit root, so p-values are invalid. • Non-constant mean and variance: these violate the stationarity assumptions underlying our forecasting and inference tools. The standard correction is to take first differences. If Visits non-stationary, then ∆Visitst = Visitst − Visitst−1 is typically stationary (I(0)), and we model the differenced series instead. dat <- dat %>% mutate(Visits_diff = Visits - lag(Visits, n = 1)) head(dat[, c("Date", "Visits", "Visits_diff")]) ## Date Visits Visits_diff ## 1 2023-01-01 1000 NA ## 2 2023-01-02 1096 96 ## 3 2023-01-03 1152 56 ## 4 2023-01-04 1167 15 ## 5 2023-01-05 1159 -8 ## 6 2023-01-06 1152 -7 14
0
You can add this document to your study collection(s)
Sign in Available only to authorized usersYou can add this document to your saved list
Sign in Available only to authorized users(For complaints, use another form )