Set-up and background

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

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?

The main question asked in this paper is how wage increases affect labor supply. The authors are seeking to understand if increasing commissions for bike messengers will affect the amount of hours they work and the amount of effort they will apply to each shift. An additional component of the experimental design aims to understand how loss aversion influences the amount of effort a bike messenger puts in during each shift when wages are increased.

[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 experimental study can control for external factors. Experimental studies conducted in controlled lab environments can be carefully tailored and controlled in a way that observational study cannot.

[Q3] Summarize the field experiment design.

Bike messengers were randomly assigned to treatment and control groups, Group A and Group B. The treatment group received an approximately 25% increase in their commission rate. Assignments into Group A and B were random and based on administrative codes assigned to the bike messengers. Group A received a 25% commission increase for four weeks in September of 2000 while Group B received their regular commission. For four weeks in November 2000, Group B received a 25% increase in their commissions while Group A received their normal wages. Both Group A and Group served as both a treatment and control group with this experimental design.

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

The laboratory experiment design focused on measuring loss-aversion by allowing participants to select between different lotteries. The experiment had two lotteries, Lottery A and Lottery B. Based on whether subjects accepted one lottery, two lotteries, or rejected both of the lotteries would determine their degree of loss aversion. This was included in the study because measuring loss aversion in the laboratory allowed experimenters to determine the Gama value of each subject. The experiments were then able to compare the relationship between loss-aversion and the effect of wages on effort per shift by the messengers.

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

The field experiment produced a variety of meaningful conclusions. First, the field experiment proved that labor supply in this experiment was very elastic. This means that as wages increased there was a large increase in labor supply. The experiment also proved that there was a very large treatment effect with respect to revenues. This means that revenues for both Group A and B went up substantially during the weeks when that group received its respective wage increase and, subsequently, returned to a lower level when that group did not receive a wage increase. The field experiment proved that the increase in labor supply was determined only by an increase in number of shifts worked. This is to say, when commissions increase, workers will take more shifts but the level of effort that they apply during each shift will decrease. Nonetheless, the increase in the number of shifts taken outweighs the diminished level of effort per shift, resulting in a large increase in total labor supply.

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

The laboratory experiment established a relationship between loss aversion and effort per shift. The lab experiment proved that the more loss aversion a subject displays, the stronger the effect of a wage increase has on decreasing their effort per shift. Ultimately, the lab experiment proved that loss averse individuals will reduce the amount of effort they put in per shift when they know that they are being paid more.

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

These results of this paper support the idea that, when individuals are paid more, they are willing to work more. While they might reduce their effort per shift, individuals will work more to make more money when they are given the opportunity. The paper also establishes the validity of reference dependent utility as it relates to effort.

This paper can be applied in the real-world when managers or business owners are trying to properly incentive workers to be productive. My first job out of college was in consulting and my bonus was determined by a variety of monthly metrics which were closely calculated by my team. When applying the findings of this paper, one can conclude that increasing the payout for bonuses will increase the amount of hours put in by each consultant and that, most likely, consultants will work enough additional hours as to increase their monthly bonus (total revenue). However, it is important to note that reference dependence and loss aversion play a major role in determining the amount of effort that each consultant will put in during their shifts. Ultimately, this paper suggests that increasing wages can be a great incentive to increase hours worked but that it is important for wage increases to proportionately follow reference points. Increasing wages for a very loss-averse team might results in a serious decrease in effort. Keeping commissions/bonuses just above individuals reference points can be a great way to incentive more work and greater effort. But, making reference points too easily accessible can greatly decrease effort. In the real-world, these findings can motivate managers to find the right balance between increasing wages to increase labor supply, while still battling diminishing effort.

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.

data = dailycorrs

p1 <- dailycorrs %>% 
  ggplot(aes(x = logv, y = logf)) + 
  geom_point() +
  geom_smooth(method = 'lm', se= FALSE) +
  xlab("Veloblitz") + 
  ylab("Flash") +
  labs(title = "Veloblitz&Flash Correlation")+
   theme_classic() 
  
p1

[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 <- dailycorrs %>%  pivot_longer(cols=c(logf, logv)) %>% 
  ggplot(aes(x = value, fill = name)) + labs(title = "Kernel Plot") + 
  geom_density(alpha = 0.3) +
  scale_fill_discrete(name = "Variables", labels = c("Flash", "Veloblitz"))


p2

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

combined_plot <- (p1 + p2 + plot_annotation(tag_levels = "A")) 

combined_plot

2.2 Tables 2 and 3

For this section please use tables1to4.csv.

tables1to4 <- 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.

Fixed effects must be controlled for in a experiment like this because bike messengers are likely very heterogeneous. This is to say, there are likely many significant differences between bike messengers that could explain some of the results observed in this experiment. For example, bike messengers might have different height, weight, muscle mass/strength, stamina, and different bike configurations (mountain bike vs. cycling bike vs. electric bike). These differences, especially the physical characteristics, are not likely to vary over time. This is to say, if one biker is very tall and strong, he will likely remain tall and strong for the months during which the experiment is conducted. Being tall and strong or having a great deal of stamina can be important characteristics necessary for working additional hours.

[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\).

tables1to4 = tables1to4 %>%
  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 <-  tables1to4 %>%
 drop_na()  %>%
  group_by(odd, block) %>%
  summarise(n=n(),
    mean_revenues = mean(totrev_fe),
    se_revenues = sd(totrev_fe) / sqrt(n()))

[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_revenues, group=odd, col=factor(odd))) +
      geom_point(position=position_dodge(width=0.5), size=3) +
      geom_errorbar(aes(x=block, ymin=mean_revenues-se_revenues, ymax=mean_revenues + se_revenues),
                    width = 0.1, position=position_dodge(width=0.5)) +
      xlab("Block") +
      ylab("Average Revenue") +
      labs(title = "P3") +
      scale_color_manual(values = c("0" = "red", "1" = "blue"),
                         labels = c("0" = "Group A", "1" = "Group B")) +
      theme_classic() + ggtitle("Average Revenue")

      
p3

[Q16] Interpret the plot.

The plot shows the average revenues for each group (A and B) when commissions are increased. Before the treatment is applied, both groups earn relatively similar average revenues. However, following the first block, the treatment group increases its average revenues greatly. Then, in the third block, when the treatment is reversed we observe the opposite. This plot shows how significant the impact of the treatment is on total revenues. When workers commissions are increased, they will work more to earn more.

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}) \]

# your code here

df <- tables1to4  %>% filter(maxhigh==1) %>% 
group_by(fahrer) %>%  mutate(high_fe = high - mean(high), block1_fe = block1 - mean(block1), block2_fe = block2 - mean(block2), block3_fe = block3 - mean(block3))


m1 <- lm(totrev_fe ~ high_fe + block2_fe + block3_fe, data = df)

summary(m1)
## 
## Call:
## lm(formula = totrev_fe ~ high_fe + block2_fe + block3_fe, data = df)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -4376.3  -656.5    46.9   831.3  3355.6 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -1.802e-13  1.123e+02   0.000 1.000000    
## high_fe      1.034e+03  2.732e+02   3.783 0.000243 ***
## block2_fe   -2.110e+02  3.126e+02  -0.675 0.501078    
## block3_fe   -5.747e+02  3.069e+02  -1.873 0.063545 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1251 on 120 degrees of freedom
## Multiple R-squared:  0.1232, Adjusted R-squared:  0.1013 
## F-statistic: 5.622 on 3 and 120 DF,  p-value: 0.00122

[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.1 <- lm(totrev ~ high + factor(block2) + factor(block3) + factor(fahrer), data = df)

m2.1
## 
## Call:
## lm(formula = totrev ~ high + factor(block2) + factor(block3) + 
##     factor(fahrer), data = df)
## 
## Coefficients:
##      (Intercept)              high   factor(block2)1   factor(block3)1  
##          1611.68           1033.56           -210.97           -574.71  
##  factor(fahrer)2   factor(fahrer)3   factor(fahrer)5   factor(fahrer)6  
##           436.70            747.20          -1270.41           1537.50  
##  factor(fahrer)7   factor(fahrer)8   factor(fahrer)9  factor(fahrer)14  
##           750.17           -106.97           3912.20            884.00  
## factor(fahrer)15  factor(fahrer)18  factor(fahrer)19  factor(fahrer)21  
##           -39.97           1327.37           2658.97           -514.13  
## factor(fahrer)22  factor(fahrer)23  factor(fahrer)24  factor(fahrer)25  
##          2955.60           3330.23           1759.17             61.17  
## factor(fahrer)28  factor(fahrer)30  factor(fahrer)31  factor(fahrer)32  
##          -150.17           1557.53           -737.97           -526.10  
## factor(fahrer)33  factor(fahrer)34  factor(fahrer)35  factor(fahrer)36  
##          2173.20           9107.03            -64.00           2054.90  
## factor(fahrer)37  factor(fahrer)38  factor(fahrer)42  factor(fahrer)44  
##          2193.97           1836.93           3938.03            521.87  
## factor(fahrer)45  factor(fahrer)49  factor(fahrer)50  factor(fahrer)51  
##           569.77           1044.20           6590.67           5288.97  
## factor(fahrer)52  factor(fahrer)53  factor(fahrer)55  factor(fahrer)56  
##          4278.30           3433.03            976.27           1761.80  
## factor(fahrer)57  factor(fahrer)58  factor(fahrer)60  factor(fahrer)61  
##          2471.53           1353.20            931.03            664.70  
## factor(fahrer)63  
##          -261.11
cluster_se <- vcovCL(m2.1, cluster = df$fahrer)

m2 <- coeftest(m2.1, vcov = cluster_se)

m2
## 
## 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 ** 
## factor(block2)1  -2.1097e+02  4.9725e+02 -4.2430e-01  0.672516    
## factor(block3)1  -5.7471e+02  5.4568e+02 -1.0532e+00  0.295454    
## factor(fahrer)2   4.3670e+02  6.0834e-12  7.1785e+13 < 2.2e-16 ***
## factor(fahrer)3   7.4720e+02  6.1385e-12  1.2172e+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  6.1857e-12  2.4856e+14 < 2.2e-16 ***
## factor(fahrer)7   7.5017e+02  7.1903e-12  1.0433e+14 < 2.2e-16 ***
## factor(fahrer)8  -1.0697e+02  6.3490e-12 -1.6848e+13 < 2.2e-16 ***
## factor(fahrer)9   3.9122e+03  6.1472e-12  6.3642e+14 < 2.2e-16 ***
## factor(fahrer)14  8.8400e+02  6.8722e-12  1.2863e+14 < 2.2e-16 ***
## factor(fahrer)15 -3.9967e+01  6.1933e-12 -6.4532e+12 < 2.2e-16 ***
## factor(fahrer)18  1.3274e+03  6.2285e-12  2.1311e+14 < 2.2e-16 ***
## factor(fahrer)19  2.6590e+03  8.7866e-12  3.0262e+14 < 2.2e-16 ***
## factor(fahrer)21 -5.1413e+02  6.1467e-12 -8.3644e+13 < 2.2e-16 ***
## factor(fahrer)22  2.9556e+03  6.3208e-12  4.6760e+14 < 2.2e-16 ***
## factor(fahrer)23  3.3302e+03  7.1260e-12  4.6733e+14 < 2.2e-16 ***
## factor(fahrer)24  1.7592e+03  6.2055e-12  2.8348e+14 < 2.2e-16 ***
## factor(fahrer)25  6.1167e+01  6.2755e-12  9.7468e+12 < 2.2e-16 ***
## factor(fahrer)28 -1.5017e+02  6.2625e-12 -2.3979e+13 < 2.2e-16 ***
## factor(fahrer)30  1.5575e+03  6.1501e-12  2.5325e+14 < 2.2e-16 ***
## factor(fahrer)31 -7.3797e+02  6.2464e-12 -1.1814e+14 < 2.2e-16 ***
## factor(fahrer)32 -5.2610e+02  6.1694e-12 -8.5276e+13 < 2.2e-16 ***
## factor(fahrer)33  2.1732e+03  6.1551e-12  3.5307e+14 < 2.2e-16 ***
## factor(fahrer)34  9.1070e+03  7.1333e-12  1.2767e+15 < 2.2e-16 ***
## factor(fahrer)35 -6.4000e+01  6.1574e-12 -1.0394e+13 < 2.2e-16 ***
## factor(fahrer)36  2.0549e+03  6.1560e-12  3.3380e+14 < 2.2e-16 ***
## factor(fahrer)37  2.1940e+03  6.1419e-12  3.5721e+14 < 2.2e-16 ***
## factor(fahrer)38  1.8369e+03  6.3206e-12  2.9063e+14 < 2.2e-16 ***
## factor(fahrer)42  3.9380e+03  6.1411e-12  6.4126e+14 < 2.2e-16 ***
## factor(fahrer)44  5.2187e+02  6.1318e-12  8.5108e+13 < 2.2e-16 ***
## factor(fahrer)45  5.6977e+02  6.4151e-12  8.8816e+13 < 2.2e-16 ***
## factor(fahrer)49  1.0442e+03  6.2792e-12  1.6629e+14 < 2.2e-16 ***
## factor(fahrer)50  6.5907e+03  6.1428e-12  1.0729e+15 < 2.2e-16 ***
## factor(fahrer)51  5.2890e+03  6.1418e-12  8.6114e+14 < 2.2e-16 ***
## factor(fahrer)52  4.2783e+03  6.1322e-12  6.9768e+14 < 2.2e-16 ***
## factor(fahrer)53  3.4330e+03  6.1367e-12  5.5942e+14 < 2.2e-16 ***
## factor(fahrer)55  9.7627e+02  6.2139e-12  1.5711e+14 < 2.2e-16 ***
## factor(fahrer)56  1.7618e+03  6.2240e-12  2.8307e+14 < 2.2e-16 ***
## factor(fahrer)57  2.4715e+03  6.1432e-12  4.0232e+14 < 2.2e-16 ***
## factor(fahrer)58  1.3532e+03  6.3263e-12  2.1390e+14 < 2.2e-16 ***
## factor(fahrer)60  9.3103e+02  6.1323e-12  1.5182e+14 < 2.2e-16 ***
## factor(fahrer)61  6.6470e+02  6.1854e-12  1.0746e+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_fe ~ high_fe + block2_fe + block3_fe, data = df)
            
m3
## OLS estimation, Dep. Var.: totrev_fe
## Observations: 124 
## Standard-errors: IID 
##                  Estimate Std. Error       t value   Pr(>|t|)    
## (Intercept) -1.310000e-14    112.299 -1.170000e-16 1.00000000    
## high_fe      1.033560e+03    273.194  3.783246e+00 0.00024293 ***
## block2_fe   -2.109725e+02    312.628 -6.748358e-01 0.50107825    
## block3_fe   -5.747125e+02    306.891 -1.872692e+00 0.06354456 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## RMSE: 1,230.2   Adj. R2: 0.101304
summary(m3)
## OLS estimation, Dep. Var.: totrev_fe
## Observations: 124 
## Standard-errors: IID 
##                  Estimate Std. Error       t value   Pr(>|t|)    
## (Intercept) -1.310000e-14    112.299 -1.170000e-16 1.00000000    
## high_fe      1.033560e+03    273.194  3.783246e+00 0.00024293 ***
## block2_fe   -2.109725e+02    312.628 -6.748358e-01 0.50107825    
## block3_fe   -5.747125e+02    306.891 -1.872692e+00 0.06354456 .  
## ---
## 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()?

The estimates in m1, m2, and m3 are all the same for variables high, block2, and block 3. The standard errors, t-values, and p-values are the same for models 1 and 3 but different for model 2. While I did not use felm() in this assignment, I did use feols(), which serves a very similar function. When applying feols() to the model with standard error, we can see that model 3 retains the same metrics for standard error, t, and p-values as model 1. Feols here is controlling for heterogeneity and addressing ommitted variable bias, resulting in more accurate significance measures and a generally more accurate fixed-effects model.

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

Clustering standard errors helps to address issues of correlation that might exist between observations. Confidence intervals and signifiance measures become more accurate when this correlation between clustered observations is accounted for.