Treatment in the following plots is defined as “spring forward” DST change in the US only. Note that times change in the US at 2:00 am on the second Sunday of March. In the EU times change at 2:00 am on the last Sunday in March. The largest window of comparison before the clocks change in the EU is 14 days.

Raw data

The raw time series (by-year and split by us/eu) is plotted over time below. The variable on the y-axis is the total count of “commits” made in the US and in the EU at the daily level. The variable on the x-axis is “Weeks since DST”. US treatment occurs at \(t = 0\). Currently the full sample is 2012-2019.

us_std |> 
  filter(between(year, 2012, 2019)) |>
  mutate(isoweek = isoweek(date),
         pre_treat_week = isoweek(treat_date_day),
         diff = isoweek - pre_treat_week - 1) |>
  ggplot(aes(x = diff, y = commits, group = wday, color = wday)) +
    geom_line() +
    geom_vline(xintercept = 0, color = "red", alpha = 0.25, size = 0.5) +
    scale_y_continuous(labels = scales::comma, limits = c(0, 130000), breaks = seq(0,130000,50000)) +
    scale_x_continuous(limits = c(-7, 7)) + 
    facet_wrap(~ year, nrow = 2) +
    scale_color_manual(values = c(grant_pal_1, grant_pal_2, grant_pal_3, grant_pal_4,
                                          grant_pal_5, grant_pal_6, grant_pal_7)) +
    hrbrthemes::theme_ipsum() +
    theme(
      panel.grid.minor = element_blank()
    ) +
    labs(
      title = "Plot 01: US - Raw time series",
      subtitle = "2012-2019",
      caption = "Data collected from ghtorrent via bigquery",
      x = "Weeks since dst",
      y = "Commits (count)",
      color = "Weekday"
    )

eu_scd |> 
  filter(between(year, 2012, 2019)) |>
  mutate(isoweek = isoweek(date),
         pre_treat_week = isoweek(treat_date_day),
         diff = isoweek - pre_treat_week - 1) |>
  ggplot(aes(x = diff, y = commits, group = wday, color = wday)) +
    geom_line() +
    geom_vline(xintercept = 0, color = "red", alpha = 0.25, size = 0.5) +
    scale_y_continuous(labels = scales::comma, limits = c(0, 130000), breaks = seq(0,130000,50000)) +
    scale_x_continuous(limits = c(-7, 7)) + 
    facet_wrap(~ year, nrow = 2) +
    scale_color_manual(values = c(grant_pal_1, grant_pal_2, grant_pal_3, grant_pal_4,
                                          grant_pal_5, grant_pal_6, grant_pal_7)) +
    hrbrthemes::theme_ipsum() +
    theme(
      panel.grid.minor = element_blank()
    ) +
    labs(
      title = "Plot 02: EU - Raw time series",
      subtitle = "2012-2019",
      caption = "Data collected from ghtorrent via bigquery",
      x = "Weeks since dst",
      y = "Commits (count)",
      color = "Weekday"
    )

Plot 03 uses standardized units. Sample means and standard deviations are separately calculated weekday-by-year across 7 weeks before and after treatment.

total |> 
  filter(between(year, 2012, 2019)) |>
  mutate(isoweek = isoweek(date),
         pre_treat_week = isoweek(treat_date_day),
         diff = isoweek - pre_treat_week - 1) |>
  ggplot(aes(x = diff, y = zcommits, group = group, color = group)) +
    geom_line() +
    geom_vline(xintercept = 0, color = "red", alpha = 0.25, size = 0.5) +
    scale_y_continuous(labels = scales::comma) +
    scale_x_continuous(limits = c(-7, 7)) + 
    # facet_grid(wday ~ year) +
    facet_grid(year ~ wday2) +
    scale_color_manual(values = c("black", azure)) +
    hrbrthemes::theme_ipsum() +
    theme(
      panel.grid.minor = element_blank(),
      legend.position = "bottom"
    ) +
    labs(
      title = "Plot 03: US - Raw time series",
      subtitle = "Weekday by year",
      caption = "Data collected from ghtorrent via bigquery",
      x = "Weeks since dst",
      y = "Std Dev",
      color = ""
    )

Plot 04 combines Plots 01 and 02 using standardized units and changes from geom_line() to geom_point().

ggplot(data = total, aes(x = diff, y = zcommits, group = wday, color = wday)) +
  geom_point(size = 1.5, alpha = 0.75) + 
  geom_vline(xintercept = 0, color = "red", alpha = 0.25, size = 0.5) +
  geom_hline(yintercept = 0, size = 0.25, linetype = "dashed") +
  facet_grid(group ~ year) +
  scale_color_manual(values = c(grant_pal_0, grant_pal_1, grant_pal_2, grant_pal_3,
                                grant_pal_4, grant_pal_6, grant_pal_7)) +
  hrbrthemes::theme_ipsum() +
  theme(
    panel.grid.minor.x = element_blank()
  ) +
  labs(
    title = "Plot 04: Demeaned time series region-by-year",
    subtitle = "TREATMENT - CONTROL",
    caption = "Data collected from ghtorrent via bigquery",
    x = "Weeks since dst",
    y = "Std dev",
    color = "Weekday"
  )

Plot 05 takes the simple difference across regions of plot 04.

ggplot(data = total_fat, aes(x = diff, y = zcommits_diffs, group = wday, color = wday)) +
  geom_point(size = 1.5, alpha = 0.75) + 
  geom_vline(xintercept = 0, color = "red", alpha = 0.25, size = 0.5) +
  geom_hline(yintercept = 0, size = 0.25, linetype = "dashed") +
  facet_grid(~ year) +
  scale_color_manual(values = c(grant_pal_1, grant_pal_2, grant_pal_3, grant_pal_4,
                                          grant_pal_5, grant_pal_6, grant_pal_7)) +
  hrbrthemes::theme_ipsum() +
  theme(
    panel.grid.minor = element_blank()
  ) +
  labs(
    title = "Plot 05: Simple difference of demeaned time series",
    caption = "Data collected from ghtorrent via bigquery",
    x = "Weeks since dst",
    y = "Std dev",
    color = "Weekday"
  )

Plot 06 takes the mean of the simple difference across years.

ggplot(data = total_fat, aes(x = diff, y = zcommits_diff, group = wday, color = wday)) +
  geom_point(size = 2.5, alpha = 0.75) + 
  # geom_line(size = 0.75) +
  geom_vline(xintercept = 0, color = "red", alpha = 0.25, size = 0.5) +
  geom_hline(yintercept = 0, size = 0.25, linetype = "dashed") +
  # facet_grid(~ year) +
  scale_color_manual(values = c(grant_pal_1, grant_pal_2, grant_pal_3, grant_pal_4,
                                          grant_pal_5, grant_pal_6, grant_pal_7)) +
  # scale_y_continuous(labels = scales::comma) +
  hrbrthemes::theme_ipsum() +
  theme(
    panel.grid.minor = element_blank()
  ) +
  labs(
    title = "Plot 06: Mean simple difference of demeaned time series",
    subtitle = "2012-2019",
    caption = "Data collected from ghtorrent via bigquery",
    x = "Weeks since dst",
    y = "Std dev",
    color = "Weekday"
  )

Event study estimates

Event studies are estimated using the following function.

feols(zCommits ~ i(days, treated, ref = -1) | year + weekday, data = full_sample)

Year and weekday fixed effects are included. zCommits is the count of commits by day standardized so the estimates are expressed in effect size. i() syntax creates a set of interact terms- one treat dummy for each period, but excluding period -1 as a reference. Equivalent to the base treat*factor(treat_date_diff) factor expansion but allows for explicit argument for a reference period.

total |> 
  esplot(sample_year = c(2012, 2019),
         sample_day = c(-20, 13),
         by_day = FALSE,
         reference = -1)

The following is the same regression but splitting by weekday.

feols(zCommits ~ i(weeks, treated, ref = -1) | year, data = weekday_sample_i)

total |> 
  esplot(sample_year = c(2012, 2019),
         sample_day = c(-34, 14),
         by_day = TRUE, reference = -1)

Results are generally the same when changing the reference group. The post period is limited to 13 days after treatment since part of the control group (2019) is treated after 14 days