Set-up and background

The assignment is worth 100 points. There are 27 questions. You should have the following packages installed:

library(tidyverse)
library(patchwork)
library(fixest)

In this problem set you will summarize the paper “Do Workers Work More if Wages Are High? Evidence from a Randomized Field Experiment” (Fehr and Goette, AER 2007) and recreate some of its findings.

1 Big picture

[Q1] What is the main question asked in this paper?

There are a few questions being asked in this paper. Overall, this paper is asking if a wage increase will impact an employee’s revenue, the amount of shifts they work, and the effort they put in to each shift. This paper is also asking if a wage increase affects employees’ effort who have varying degrees of loss aversion.

[Q2] Recall the taxi cab studies where reference dependence is studied using observational data. What can an experimental study do that an observational study can’t?

The benefit of an experimental study is that it allows the researches to control more of the environment. In an observational study, especially one concerning a wage increase, the change in messenger behavior could be due to loads of other factors. However, in an experimental study, the treatment group is in a fully controlled environment compared to the control group. This makes the results stronger because the factor you created is the only one that affects the treatment group and nothing else.

[Q3] Summarize the field experiment design.

The field experiment design took messengers willing to participate in the experiment and randomly assigned them to two different groups. Each group took a turn being both the treatment and control group. In the first four weeks, the treatment group experienced a 25% wage increase while the control group did not experience any change. Once that was complete and a small break was taken, the two groups switched and the previous control group experienced a 25% wage increase for four weeks while the previous treatment group went back to the normal wage.

[Q4] Summarize the laboratory experiment design. Why was it included with the study?

The researchers wanted to see if a dominant personality trait like loss-aversion also played a roll in the results of the field experiment. In order to achieve this, the authors set up a lottery experiment that occurred 8 months after the initial field experiment. The 42 messengers who participated in the field experiment were given the choice between two different lotteries. Lottery A was more risky than Lottery B. The messengers could choose both, neither, or one or the other. It was expected that if the messenger rejected B then they also rejected A since A was riskier.

[Q5] Summarize the main results of the field experiment.

The field experiment wanted to answer a few questions. First up, did the wage increase impact the total revenue made by each messenger? The answer was a resounding yes. For both groups, when they were the treatment group, the treatment effect was about a 1,000 CHF increase. The was significant because before the experiment both groups were earning roughly the same. The second question was did the wage increase impact the number of shifts worked per messenger? The answer was once again yes. The treatment effect for both groups was about a four shift increase from pre-experiment times. Finally, the authors wanted to see if the wage increases impacted the amount of effort each messenger put in during a shift. The answer was surprisingly no. In both groups, the control group (which was earning less) earned about 5% more per shift than the treatment group. This means that even though total revenue went up per messenger because of the wage increase, the effort given in each shift was less.

[Q6] Summarize the main results of the laboratory experiment.

The lab experiment wanted to determine if loss-aversion explained the negative impact on effort per shift that was discovered in the field experiment. The authors found that messengers that display no signs of loss aversion do not change their effort per shift, regardless of the wage increase. However, the messengers that display even a little loss aversion decrease their effort per shift. This suggests that the lack of effort per shift in the field experiment can be do to the degree of loss aversion per messenger.

[Q7] Why are these results valuable? What have we learned? Motivate your discussion with a real-world example.

I feel like these results are valuable for a multitude of reasons. We learned that if you increase wages, people will make more money and work more shifts, but their effort per shift will go down if they are even a little bit loss averse. I feel like people in general, especially with age, tend to be somewhat loss averse. So, if someone knows their revenue is going to increase, which is guaranteed money, they no longer need to work as hard because the money is guaranteed. This applies to the minimum wage debate because the nation right now is divided on whether or not we should increase the national minimum wage. Some people argue that if you increase the minimum wage, people will not work as hard and business owners will go under from the added costs. This paper seems to imply that increasing the minimum wage will indeed decrease the employee’s effort, however, they will also pick up more shifts. Personally, I think a minimum wage increase is long overdue because of how much inflation has gone up over the past few decades.

2 Replication

Use theme_classic() for all plots.

2.1 Correlations in revenues across firms

For this section please use dailycorrs.csv.

dailycorrs = read_csv("dailycorrs.csv")

[Q8] The authors show that earnings at Veloblitz and Flash are correlated. Show this with a scatter plot with a regression line and no confidence interval. Title your axes and the plot appropriately. Do not print the plot but assign it to an object called p1.

p1 <- ggplot(dailycorrs, aes(x=logv, y=logf)) +
      geom_point() +
      geom_smooth(method=lm, se=FALSE) +
      xlab("Veloblitz Earnings") +
      ylab("Flash Earnings") +
      labs(title = "Plot A") +
      theme_classic()

[Q9] Next plot the kernel density estimates of revenues for both companies. Overlay the distributions and make the densities transparent so they are easily seen. Title your axes and the plot appropriately. Do not print the plot but assign it to an object called p2.

p2 <- ggplot(dailycorrs) +
      geom_density(aes(x=logv), fill = "red", alpha = 0.1) +
      geom_density(aes(x=logf), fill = "blue", alpha = 0.1) +
      xlab("Earnings") +
      ylab("Density") +
      labs(title = "Plot B") +
      theme_classic()

[Q11] Now combine both plots using library(patchwork) and label the plots with letters.

p1 | p2

2.2 Tables 2 and 3

For this section please use tables1to4.csv.

tables = read_csv("tables1to4.csv")

2.2.1 Table 2

On page 307 the authors write:

“Table 2 controls for individual fixed effects by showing how, on average, the messengers’ revenues deviate from their person-specific mean revenues. Thus, a positive number here indicates a positive deviation from the person-specific mean; a negative number indicates a negative deviation.”

[Q12] Fixed effects are a way to control for heterogeneity across individuals that is time invariant. Why would we want to control for fixed effects? Give a reason how bike messengers could be different from each other, and how these differences might not vary over time.

Generally, the reason we control for fixed effects is to remove omitted variable bias. This means that we can analyze changes in in-group variables that are affected by time (think revenue and number of shifts). Examples of variables that are not affected by time include sex, gender, race, and ethnicity. All of these could apply to the bike messengers in our experiment and will not change over time (unless a messenger becomes transgender).

[Q13] Create a variable called totrev_fe and add it to the dataframe. This requires you to “average out” each individual’s revenue for a block from their average revenue: \(x_i^{fe} = x_{it} - \bar{x}_i\) where \(x_i^{fe}\) is the fixed effect revenue for \(i\).

tables = tables %>%
  group_by(fahrer) %>%
  mutate(totrev_fe = totrev - mean(totrev))

[Q14] Use summarise() to recreate the findings in Table 2 for “Participating Messengers” using your new variable totrev_fe. (You do not have to calculate the differences in means.)

In addition to calculating the fixed-effect controled means, calculate the standard errors. Recall the standard error is \(\frac{s_{jt}}{\sqrt{n_{jt}}}\) where \(s_{jt}\) is the standard deviation for treatment \(j\) in block \(t\) and \(n_{jt}\) are the corresponding number of observations.

(Hint: use n() to count observations.) Each calculation should be named to a new variable. Assign the resulting dataframe to a new dataframe called df_avg_revenue.

df_avg_revenue <- tables %>%
  drop_na(odd) %>%
  group_by(odd, block) %>%
  summarise(n=n(),
            mean_rev = mean(totrev_fe),
            se_rev = sd(totrev_fe)/sqrt(n))

df_avg_revenue
## # A tibble: 6 x 5
## # Groups:   odd [2]
##     odd block     n mean_rev se_rev
##   <dbl> <dbl> <int>    <dbl>  <dbl>
## 1     0     1    19   -120.    303.
## 2     0     2    20   -278.    241.
## 3     0     3    20    392.    251.
## 4     1     1    21    -48.9   361.
## 5     1     2    22    722.    193.
## 6     1     3    22   -675.    289.

[Q15] Plot df_avg_revenue. Use points for the means and error bars for standard errors of the means.

To dodge the points and size them appropriately, use

geom_point(position=position_dodge(width=0.5), size=4)

To place the error bars use

geom_errorbar(aes(
  x=block, 
  ymin = [MEAN] - [SE], ymax = [MEAN] + [SE]),
  width = .1,
  position=position_dodge(width=0.5))

You will need to replace [MEAN] with whatever you named your average revenues and [SE] with whatever you named your standard errors.

p3 <- ggplot(df_avg_revenue, aes(x=block, y=mean_rev, group=odd, col=factor(odd))) +
      geom_point(position=position_dodge(width=0.5), size=4) +
      geom_errorbar(aes(x=block, ymin=mean_rev-se_rev, ymax=mean_rev + se_rev),
                    width = 0.1, position=position_dodge(width=0.5)) +
      xlab("Block") +
      ylab("Average Revenue") +
      labs(title = "Plot C", fill = "Odd") +
      theme_classic()
      
p3

[Q16] Interpret the plot.

Error bars show how much variance there is around the mean of the variable. With this particular graph, the ‘odd’ variable denotes the messengers in group A versus group B. The ‘block’ variable denotes what time each group was the treatment versus control group. ‘Average revenue’ is self-explanatory. These error bars show how large the difference is between the mean average revenue and the standard error of the average revenue. In an ideal world, these error bars would be very small. If the standard error is big it means the data may have some irregularities. In this particular graph, it seems that the first block has a similar average revenue (circle in the middle), but that one of the groups has a larger standard error. What gets interesting is that the other two blocks have large differences in average revenue even though the standard errors are not as large as the first block. Ideally, because each group acts as both the control and treatment at some point, the mean average revenue would be similar because it means that each group behaves similarly. However, we see large differences in average revenues between the 2 groups.

2.2.2 Table 3

[Q17] Recreate the point estimates in Model (1) in Table 3 by hand (you don’t need to worry about the standard errors). Assign it to object m1. Recreating this model requires you to control for individual fixed effects and estimate the following equation where \(\text{H}\) is the variable high, \(\text{B2}\) is the second block (block == 2) and \(\text{B3}\) is the third block (block == 3):

\[ y_{ijt} - \bar{y}_{ij} = \beta_1 (\text{H}_{ijt} - \bar{\text{H}}_{ij}) + \beta_2 (\text{B2}_{ijt} - \bar{\text{B2}}_{ij}) + \beta_3 (\text{B3}_{ijt} - \bar{\text{B3}}_{ij}) + (\varepsilon_{ijt} - \bar{\varepsilon}_{ij}) \]

tables = tables %>%
  group_by(fahrer) %>%
  mutate(totrev_mean = totrev - mean(totrev),
         high_mean = high - mean(high),
         block2_mean = block2 - mean(block2),
         block3_mean = block3 - mean(block3))

m1 <- lm(totrev_mean ~ high_mean + block2_mean + block3_mean, data = tables %>% filter(maxhigh==1))

m1
## 
## Call:
## lm(formula = totrev_mean ~ high_mean + block2_mean + block3_mean, 
##     data = tables %>% filter(maxhigh == 1))
## 
## Coefficients:
## (Intercept)    high_mean  block2_mean  block3_mean  
##  -2.332e-13    1.034e+03   -2.110e+02   -5.747e+02

[Q18] Now recreate the same point estimates using lm and assign it to object m2. You are estimating the model below where where \(\text{F}_i\) is the dummy variable for each messenger (fahrer). Make sure to cluster the standard errors at the messenger level. (Use lmtest and sandwhich for this.)

\[ y_{ijt} - \beta_0 + \beta_1 \text{H}_{ijt} + \beta_2 \text{B2}_{ijt} + \beta_3 \text{B3}_{ijt} + \sum_{i=1}^{n} \alpha_i \text{F}_i + \varepsilon_{ijt} \]

m2 <- lm(totrev ~ high + block2 + block3 + factor(fahrer), data = tables %>% filter(maxhigh==1))

library(lmtest)
library(sandwich)

m2_clus <- coeftest(m2, vcov=vcovCL, cluster = ~fahrer)

m2_clus
## 
## t test of coefficients:
## 
##                     Estimate  Std. Error     t value  Pr(>|t|)    
## (Intercept)       1.6117e+03  2.9297e+02  5.5012e+00 4.509e-07 ***
## high              1.0336e+03  3.2685e+02  3.1621e+00  0.002222 ** 
## block2           -2.1097e+02  4.9725e+02 -4.2430e-01  0.672516    
## block3           -5.7471e+02  5.4568e+02 -1.0532e+00  0.295454    
## factor(fahrer)2   4.3670e+02  6.1699e-12  7.0779e+13 < 2.2e-16 ***
## factor(fahrer)3   7.4720e+02  5.1180e-12  1.4599e+14 < 2.2e-16 ***
## factor(fahrer)5  -1.2704e+03  1.4648e+02 -8.6727e+00 4.240e-13 ***
## factor(fahrer)6   1.5375e+03  5.7540e-12  2.6721e+14 < 2.2e-16 ***
## factor(fahrer)7   7.5017e+02  5.2566e-12  1.4271e+14 < 2.2e-16 ***
## factor(fahrer)8  -1.0697e+02  5.1039e-12 -2.0958e+13 < 2.2e-16 ***
## factor(fahrer)9   3.9122e+03  5.2902e-12  7.3952e+14 < 2.2e-16 ***
## factor(fahrer)14  8.8400e+02  5.3399e-12  1.6555e+14 < 2.2e-16 ***
## factor(fahrer)15 -3.9967e+01  5.2990e-12 -7.5424e+12 < 2.2e-16 ***
## factor(fahrer)18  1.3274e+03  5.1262e-12  2.5894e+14 < 2.2e-16 ***
## factor(fahrer)19  2.6590e+03  1.1817e-11  2.2502e+14 < 2.2e-16 ***
## factor(fahrer)21 -5.1413e+02  6.2731e-12 -8.1958e+13 < 2.2e-16 ***
## factor(fahrer)22  2.9556e+03  5.1183e-12  5.7745e+14 < 2.2e-16 ***
## factor(fahrer)23  3.3302e+03  5.1318e-12  6.4894e+14 < 2.2e-16 ***
## factor(fahrer)24  1.7592e+03  5.6287e-12  3.1253e+14 < 2.2e-16 ***
## factor(fahrer)25  6.1167e+01  5.6503e-12  1.0825e+13 < 2.2e-16 ***
## factor(fahrer)28 -1.5017e+02  5.1918e-12 -2.8924e+13 < 2.2e-16 ***
## factor(fahrer)30  1.5575e+03  5.1325e-12  3.0347e+14 < 2.2e-16 ***
## factor(fahrer)31 -7.3797e+02  5.1419e-12 -1.4352e+14 < 2.2e-16 ***
## factor(fahrer)32 -5.2610e+02  5.1484e-12 -1.0219e+14 < 2.2e-16 ***
## factor(fahrer)33  2.1732e+03  5.1624e-12  4.2097e+14 < 2.2e-16 ***
## factor(fahrer)34  9.1070e+03  4.9957e-12  1.8230e+15 < 2.2e-16 ***
## factor(fahrer)35 -6.4000e+01  5.1438e-12 -1.2442e+13 < 2.2e-16 ***
## factor(fahrer)36  2.0549e+03  5.2160e-12  3.9396e+14 < 2.2e-16 ***
## factor(fahrer)37  2.1940e+03  5.1583e-12  4.2533e+14 < 2.2e-16 ***
## factor(fahrer)38  1.8369e+03  5.1612e-12  3.5591e+14 < 2.2e-16 ***
## factor(fahrer)42  3.9380e+03  5.4985e-12  7.1620e+14 < 2.2e-16 ***
## factor(fahrer)44  5.2187e+02  5.1491e-12  1.0135e+14 < 2.2e-16 ***
## factor(fahrer)45  5.6977e+02  5.3733e-12  1.0604e+14 < 2.2e-16 ***
## factor(fahrer)49  1.0442e+03  6.2645e-12  1.6669e+14 < 2.2e-16 ***
## factor(fahrer)50  6.5907e+03  5.1539e-12  1.2788e+15 < 2.2e-16 ***
## factor(fahrer)51  5.2890e+03  5.1441e-12  1.0282e+15 < 2.2e-16 ***
## factor(fahrer)52  4.2783e+03  5.1499e-12  8.3075e+14 < 2.2e-16 ***
## factor(fahrer)53  3.4330e+03  5.7537e-12  5.9667e+14 < 2.2e-16 ***
## factor(fahrer)55  9.7627e+02  6.1927e-12  1.5765e+14 < 2.2e-16 ***
## factor(fahrer)56  1.7618e+03  5.6151e-12  3.1376e+14 < 2.2e-16 ***
## factor(fahrer)57  2.4715e+03  5.1982e-12  4.7546e+14 < 2.2e-16 ***
## factor(fahrer)58  1.3532e+03  5.1264e-12  2.6397e+14 < 2.2e-16 ***
## factor(fahrer)60  9.3103e+02  5.1815e-12  1.7968e+14 < 2.2e-16 ***
## factor(fahrer)61  6.6470e+02  5.1447e-12  1.2920e+14 < 2.2e-16 ***
## factor(fahrer)63 -2.6111e+02  1.4648e+02 -1.7825e+00  0.078504 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

[Q20] Now use feols to recreate Model (1), including the standard errors. Assign your estimates to the object m3. You are estimating the model below where where \(\alpha_i\) is the individual intercept (i.e. the individual fixed effect):

\[ y_{ijt} = \alpha_i + \beta_1 \text{H}_{ijt} + \beta_2 \text{B2}_{ijt} + \beta_3 \text{B3}_{ijt} + \varepsilon_{ijt} \]

m3 <- feols(totrev_mean ~ high_mean + block2_mean + block3_mean, data = tables %>% filter(maxhigh==1))

summary(m3)
## OLS estimation, Dep. Var.: totrev_mean
## Observations: 124 
## Standard-errors: Standard 
##                Estimate Std. Error      t value Pr(>|t|))    
## (Intercept) -3.0900e-14     112.30 -2.75000e-16  1.000000    
## high_mean    1.0336e+03     273.19  3.78320e+00  0.000243 ***
## block2_mean -2.1097e+02     312.63 -6.74836e-01  0.501078    
## block3_mean -5.7471e+02     306.89 -1.87270e+00  0.063545 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## RMSE: 1,230.2   Adj. R2: 0.101304
summary(m3, cluster = "fahrer")
## OLS estimation, Dep. Var.: totrev_mean
## Observations: 124 
## Standard-errors: Clustered (fahrer) 
##                Estimate Std. Error   t value Pr(>|t|))    
## (Intercept) -3.0900e-14 4.0700e-14 -0.759010  0.452188    
## high_mean    1.0336e+03 2.6520e+02  3.897300  0.000353 ***
## block2_mean -2.1097e+02 4.0346e+02 -0.522911  0.603851    
## block3_mean -5.7471e+02 4.4275e+02 -1.298100  0.201523    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## RMSE: 1,230.2   Adj. R2: 0.101304

[Q21] Compare the estimates in m1, m2 and m3. What is the same? What is different? What would you say is the main advantage of using felm()?

In all 3 models the coefficients rounded to the same estimate. However, model 2 is the only model that had the correct standard errors. This model clustered the standard errors like model 3, but it also included a dummy variable for each messenger. The standard errors in model 3 are all a bit lower than what they are in the paper.

[Q22] Explain why you need to cluster the standard errors.

This paper wants to explore how bike messengers in Switzerland react to a wage increase. Do they work harder? Take on more shifts? Everything in this research paper looks at two separate groups of messengers and how they react to a known wage increase. Clustered standard errors around the messenger variables allows us to control for any correlation between messengers in the same group.