# load all packages
library(tidyverse)
library(stargazer)
library(here) # see https://www.tidyverse.org/blog/2017/12/workflow-vs-script/
library(readxl)
# library(xlsx)
library(knitr)
library(ggrepel)
library(gridExtra) # for combining plots
library(grid)
require(scales)
library(ggsignif)
library(table1) # https://cran.r-project.org/web/packages/table1/vignettes/table1-examples.html
library(ggpubr) # for figure_annotate
# packages for regressions:
library(MASS)
library(multiwayvcov)
library(pscl) # for pseudo r2
library(sandwich)
library(lmtest)   # waldtest; see also coeftest.


# overwrite select and filter functions 
select <- dplyr::select
filter <- dplyr::filter

# load data
df <- readRDS(here("clean data", 'df_anonymous'))

# exclude lowest 5% of time distribution
df <- df %>% 
  filter(duration >= 158) # removing 32 respondents who answered the survey questions too quickly, following preregistration

df <- df %>% 
  mutate(gender_f = case_when(gender == "Female" ~ 1, TRUE ~ 0))

Tables

Table 1: Descriptive statistics

df.table1 <- df %>% 
  mutate(gender_ = case_when(is.na(gender) ~ "Other", TRUE ~ gender),
         occupation_ = case_when(occupation == "Retired" | occupation ==  "Disabled" | occupation == "Other" ~ "Other",
                                 is.na(occupation) ~ "Other",
                                 TRUE ~ as.character(occupation)),
         occupation_ = factor(occupation_, 
                              levels = c("Student", "Platform work", "Self-employed", "Parttime", "Fulltime",  "Other")))

my.render.cont <- function(x) {
  with(stats.apply.rounding(stats.default(x), digits=2), c("",
                                                           "Mean (SD)"=sprintf("%s (&plusmn; %s)", MEAN, SD)))
}
my.render.cat <- function(x) {
  c("", sapply(stats.default(x), function(y) with(y,
                                                  sprintf("%d (%0.0f%%)", FREQ, PCT))))
}
data <- c(split(df.table1, df.table1$treatment),list(Total=df.table1))
labels <- list(
  variables=list(gender_="Gender",
                 age="Age (years)",
                 occupation_ = "Main occupation",
                 income_num = "Net household income/month",
                 hours_platform = "Hours/week work via platform",
                 hours_platform_prop = "Hours of workweek via platform",
                 trust_others = "General trust",
                 trust_govt = "Trust in government",
                 trust_platforms = "Trust in platforms",
                 self_report_know = "Self-reported tax knowledge"))
# note to self: Table1 is really hard to export to Latex. I opened the HTML version in a browser, and copy-pasted the source code here: https://tableconvert.com/?output=latex. I made manual corrections to the formatting in the Overleaf document.  
table1(data, labels, render.continuous=my.render.cont, render.categorical=my.render.cat)
Control
(N=313)
Information
(N=313)
Total
(N=626)
Gender
Female 110 (35%) 99 (32%) 209 (33%)
Male 199 (64%) 208 (66%) 407 (65%)
Other 4 (1%) 6 (2%) 10 (2%)
Age (years)
Mean (SD) 22 (± 6.5) 22 (± 7.2) 22 (± 6.9)
Main occupation
Student 188 (60%) 185 (59%) 373 (60%)
Platform work 39 (12%) 41 (13%) 80 (13%)
Self-employed 32 (10%) 35 (11%) 67 (11%)
Parttime 26 (8%) 21 (7%) 47 (8%)
Fulltime 15 (5%) 14 (4%) 29 (5%)
Other 13 (4%) 17 (5%) 30 (5%)
Net household income/month
Mean (SD) 2500 (± 2000) 2300 (± 1900) 2400 (± 1900)
Missing 74 (23.6%) 74 (23.6%) 148 (23.6%)
Hours/week work via platform
Mean (SD) 11 (± 9.3) 12 (± 10) 12 (± 9.9)
Hours of workweek via platform
Zero 29 (9%) 28 (9%) 57 (9%)
Less than half 78 (25%) 75 (24%) 153 (24%)
Half 53 (17%) 56 (18%) 109 (17%)
More than half 59 (19%) 68 (22%) 127 (20%)
Only income 94 (30%) 86 (27%) 180 (29%)
General trust
Mean (SD) 3.6 (± 0.86) 3.6 (± 0.86) 3.6 (± 0.86)
Missing 8 (2.6%) 8 (2.6%) 16 (2.6%)
Trust in government
Mean (SD) 3.4 (± 1.0) 3.4 (± 1.0) 3.4 (± 1.0)
Missing 11 (3.5%) 12 (3.8%) 23 (3.7%)
Trust in platforms
Mean (SD) 3.4 (± 0.79) 3.4 (± 0.80) 3.4 (± 0.79)
Missing 7 (2.2%) 6 (1.9%) 13 (2.1%)
Self-reported tax knowledge
Mean (SD) 3.6 (± 0.82) 3.7 (± 0.89) 3.6 (± 0.86)
rm(df.table1, labels, my.render.cat, my.render.cont, data)

Table 2: Ordered probit regressions of expected supply

# first de-mean trust
df <- df %>% 
  mutate(trust_govt_dm = scale(trust_govt, scale = F),
         trust_platforms_dm = scale(trust_platforms, scale = F))

oprob1 <- polr(supply ~ treatment, data=df, Hess=TRUE, method="probit")
oprob2 <- polr(supply ~ treatment * trust_govt_dm,  data=df, Hess=TRUE, method="probit")
oprob3 <- polr(supply ~ treatment * trust_govt_dm + trust_platforms_dm + gender_f + age + only_income + hours_platform,  data=df, Hess=TRUE, method="probit")
oprob4 <- polr(supply ~ treatment * trust_govt_dm + trust_platforms_dm + gender_f + age + only_income + hours_platform + self_report_know,  data=df, Hess=TRUE, method="probit")

# could check interaction gender * treatment already now:
oprob5 <- polr(supply ~ treatment * gender_f + trust_govt_dm + trust_platforms_dm + age + only_income + hours_platform,  data=df, Hess=TRUE, method="probit")
# could also check interaction hours_platform * treatment already now:
oprob6 <- polr(supply ~ treatment * hours_platform + gender_f + trust_govt_dm + trust_platforms_dm + age + only_income,  data=df, Hess=TRUE, method="probit")

McFadden.oprob1 <- round(pR2(oprob1)["McFadden"],3)
LL.oprob1 <- round(pR2(oprob1)["llh"],1)
McFadden.oprob2 <- round(pR2(oprob2)["McFadden"],3)
LL.oprob2 <- round(pR2(oprob2)["llh"],1)
McFadden.oprob3 <- round(pR2(oprob3)["McFadden"],3)
LL.oprob3 <- round(pR2(oprob3)["llh"],1)
McFadden.oprob4 <- round(pR2(oprob4)["McFadden"],3)
LL.oprob4 <- round(pR2(oprob4)["llh"],1)

# cluster robust standard errors (for ordered probit you need CL)
coefs1 <- coeftest(oprob1, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust1 <- vcovCL(oprob1, type = "HC1") # HC1 reproduces STATA default
robust_se1    <- sqrt(diag(cov_robust1))
coefs2 <- coeftest(oprob2, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust2 <- vcovCL(oprob2, type = "HC1") # HC1 reproduces STATA default
robust_se2    <- sqrt(diag(cov_robust2))
coefs3 <- coeftest(oprob3, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust3 <- vcovCL(oprob3, type = "HC1") # HC1 reproduces STATA default
robust_se3    <- sqrt(diag(cov_robust3))
coefs4 <- coeftest(oprob4, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust4 <- vcovCL(oprob4, type = "HC1") # HC1 reproduces STATA default
robust_se4    <- sqrt(diag(cov_robust4))
#  text output in R markdown
stargazer(oprob1, oprob2, oprob3, oprob4,
          se = list(robust_se1, robust_se2, robust_se3, robust_se4
                    ),
          type = "html",
          keep.stat = c("rsq", "n"),
          intercept.bottom = FALSE,
          header=FALSE,
          title = "Ordered probit regressions of expected supply",
          covariate.labels = c("Information treatment (ref = Control)", "Information treatment X Trust in government",
                               "Trust in government", "Trust in platforms",  "Gender (1 = female)",
                               "Age", "Full-time platform work" ,"Hours/week working on platform", "Self-reported tax knowledge"),
          order = c(1, 9, 2:8),
          model.names = FALSE,
          no.space = TRUE,
          dep.var.labels = "",
          dep.var.caption = "DV: expected supply",
          add.lines = list(c("Log likelihood", LL.oprob1, LL.oprob2, LL.oprob3, LL.oprob4
                             ),
                           c("Pseudo $R^2$ (McFadden)",
                             McFadden.oprob1, McFadden.oprob2, McFadden.oprob3, McFadden.oprob4
                             )),
          star.cutoffs = c(0.05, 0.01, 0.001))
Ordered probit regressions of expected supply
DV: expected supply
(1) (2) (3) (4)
Information treatment (ref = Control) -0.537*** -0.549*** -0.552*** -0.560***
(0.094) (0.096) (0.097) (0.097)
Information treatment X Trust in government 0.058 0.055 0.042
(0.087) (0.089) (0.090)
Trust in government 0.038 0.023 0.017
(0.072) (0.074) (0.075)
Trust in platforms 0.004 -0.009
(0.062) (0.062)
Gender (1 = female) -0.105 -0.084
(0.101) (0.102)
Age -0.013 -0.014
(0.008) (0.008)
Full-time platform work 0.101 0.111
(0.109) (0.109)
Hours/week working on platform -0.004 -0.004
(0.006) (0.006)
Self-reported tax knowledge 0.091
(0.060)
Log likelihood -618.2 -594.9 -590.1 -588.8
Pseudo R(McFadden) 0.028 0.031 0.037 0.039
Observations 626 603 601 601
Note: p<0.05; p<0.01; p<0.001

Table 3: Probit regressions of expect to work more

df <- df %>% 
  mutate(supply_more = case_when(supply == "More" ~ 1, TRUE ~ 0),
         student = case_when(occupation == "Student" ~ 1, TRUE ~ 0))

oprob1 <- glm(supply_more ~ treatment, family = binomial(link = "probit"), data = df)
oprob2 <- glm(supply_more ~ treatment * gender_f, family = binomial(link = "probit"), data = df)
oprob3 <- glm(supply_more ~ treatment * hours_platform, family = binomial(link = "probit"), data = df)
oprob4 <- glm(supply_more ~ treatment * age, family = binomial(link = "probit"), data = df)
oprob5 <- glm(supply_more ~ treatment * only_income, family = binomial(link = "probit"), data = df)
oprob_unused <- glm(supply_more ~ treatment * income_num, family = binomial(link = "probit"), data = df)

oprob6 <- glm(supply_more ~ treatment * gender_f + treatment*hours_platform + treatment*age +
                treatment*only_income + treatment*self_report_know, family = binomial(link = "probit"), data = df)

oprob7 <- glm(supply_more ~ treatment * self_report_know, family = binomial(link = "probit"), data = df)

McFadden.oprob1 <- round(pR2(oprob1)["McFadden"],3)
LL.oprob1 <- round(pR2(oprob1)["llh"],1)
McFadden.oprob2 <- round(pR2(oprob2)["McFadden"],3)
LL.oprob2 <- round(pR2(oprob2)["llh"],1)
McFadden.oprob3 <- round(pR2(oprob3)["McFadden"],3)
LL.oprob3 <- round(pR2(oprob3)["llh"],1)
McFadden.oprob4 <- round(pR2(oprob4)["McFadden"],3)
LL.oprob4 <- round(pR2(oprob4)["llh"],1)
McFadden.oprob5 <- round(pR2(oprob5)["McFadden"],3)
LL.oprob5 <- round(pR2(oprob5)["llh"],1)
McFadden.oprob6 <- round(pR2(oprob6)["McFadden"],3)
LL.oprob6 <- round(pR2(oprob6)["llh"],1)
McFadden.oprob7 <- round(pR2(oprob7)["McFadden"],3)
LL.oprob7 <- round(pR2(oprob7)["llh"],1)


# cluster robust standard errors (for ordered probit you need CL)
coefs1 <- coeftest(oprob1, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust1 <- vcovCL(oprob1, type = "HC1") # HC1 reproduces STATA default
robust_se1    <- sqrt(diag(cov_robust1))
coefs2 <- coeftest(oprob2, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust2 <- vcovCL(oprob2, type = "HC1") # HC1 reproduces STATA default
robust_se2    <- sqrt(diag(cov_robust2))
coefs3 <- coeftest(oprob3, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust3 <- vcovCL(oprob3, type = "HC1") # HC1 reproduces STATA default
robust_se3    <- sqrt(diag(cov_robust3))
coefs4 <- coeftest(oprob4, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust4 <- vcovCL(oprob4, type = "HC1") # HC1 reproduces STATA default
robust_se4   <- sqrt(diag(cov_robust4))
coefs5 <- coeftest(oprob5, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust5 <- vcovCL(oprob5, type = "HC1") # HC1 reproduces STATA default
robust_se5    <- sqrt(diag(cov_robust5))
coefs6 <- coeftest(oprob6, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust6 <- vcovCL(oprob6, type = "HC1") # HC1 reproduces STATA default
robust_se6    <- sqrt(diag(cov_robust6))
coefs7 <- coeftest(oprob7, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust7 <- vcovCL(oprob7, type = "HC1") # HC1 reproduces STATA default
robust_se7    <- sqrt(diag(cov_robust7))
#  text output in R markdown
stargazer(oprob1, oprob2, oprob4, oprob5, oprob3, oprob7, oprob6,
          se = list(robust_se1, robust_se2, robust_se4, robust_se5, robust_se3, robust_se7, robust_se6),
          type = "html",
          keep.stat = c("rsq", "n"),
          intercept.bottom = FALSE,
          header=FALSE,
          title = "Probit regressions of binary expected supply (1 = More)",
          covariate.labels = c("Constant", "Information (ref = Control)",
                               "Gender (1 = female)", "Information X Female",
                               "Age", "Information X Age",
                               "Full-time platform work", "Information X Full-time platform work",
                               "Hours/week working on platform", "Information X Hours/w working on platform",
                               "Self-reported tax knowledge", "Information X Self-reported tax knowledge"),
          model.names = FALSE,
          no.space = TRUE,
          dep.var.labels = "",
          dep.var.caption = "DV: expect to supply more",
          add.lines = list(c("Log likelihood", LL.oprob1, LL.oprob2, LL.oprob4, LL.oprob5, LL.oprob3, LL.oprob7, LL.oprob6),
                           c("Pseudo $R^2$ (McFadden)",
                             McFadden.oprob1, McFadden.oprob2, McFadden.oprob4, McFadden.oprob5, McFadden.oprob3, McFadden.oprob7, McFadden.oprob6)),
          star.cutoffs = c(0.05, 0.01, 0.001))
Probit regressions of binary expected supply (1 = More)
DV: expect to supply more
(1) (2) (3) (4) (5) (6) (7)
Constant -0.012 -0.031 0.460 -0.017 0.111 -0.223 0.233
(0.071) (0.088) (0.269) (0.085) (0.109) (0.317) (0.440)
Information (ref = Control) -1.010*** -0.858*** -1.566*** -1.120*** -1.436*** -1.141* -1.697**
(0.112) (0.133) (0.396) (0.136) (0.182) (0.530) (0.649)
Gender (1 = female) 0.054 0.073
(0.149) (0.154)
Information X Female -0.564* -0.515
(0.256) (0.266)
Age -0.022 -0.020
(0.012) (0.012)
Information X Age 0.026 0.021
(0.018) (0.018)
Full-time platform work 0.017 0.043
(0.155) (0.162)
Information X Full-time platform work 0.351 0.213
(0.241) (0.257)
Hours/week working on platform -0.011 -0.009
(0.007) (0.008)
Information X Hours/w working on platform 0.034** 0.028*
(0.011) (0.012)
Self-reported tax knowledge 0.058 0.069
(0.086) (0.089)
Information X Self-reported tax knowledge 0.033 -0.012
(0.140) (0.137)
Log likelihood -351.1 -347.8 -349.1 -349.1 -345.8 -350.4 -340.3
Pseudo R(McFadden) 0.11 0.118 0.115 0.115 0.123 0.112 0.137
Observations 626 626 626 626 626 626 626
Note: p<0.05; p<0.01; p<0.001

Figures

Figure 1: Main treatment effect

df <- df %>% 
  mutate(supply_num = case_when(supply == "Less" ~ -1,
                                supply == "Same" ~ 0,
                                supply == "More" ~ 1))
MWW_supply <- round(wilcox.test(supply_num ~ treatment, data=df, alternative = "greater")$p.value, 3) # 0.000, one-sided, ** in figure

proportion <- df %>%  # calculate percentages of each category
  select(treatment, supply) %>%
  group_by(treatment, supply) %>%
  tally() %>%
  group_by(treatment) %>%
  mutate(pct = n / sum(n))

chi_table <- table(df$treatment, df$supply)
chisq.test(chi_table)
## 
##  Pearson's Chi-squared test
## 
## data:  chi_table
## X-squared = 98.237, df = 2, p-value < 2.2e-16
chi_supply <- round(chisq.test(chi_table)$p.value, 3)

main_treatment_effect <- ggplot(proportion, aes(treatment, pct, fill = as.factor(supply))) +
  geom_bar(stat = "identity", color = "grey", width = 0.7) +
  labs(fill = "", x = "", y = "Percentage of respondents \n",
       caption = "*** chi^2 test p < 0.001", title = "How many hours do you expect to work via platforms,\nin the coming 2 years?"
       ) +
  scale_fill_brewer(palette = "PRGn")+
  scale_y_continuous(limits = c(0,1.15), # to make some space for labels
                     breaks = c(0,0.25,0.5, 0.75, 1), 
                     labels = c("0%", "25%", "50%", "75%", "100%")) +
  theme_bw() +
  theme(axis.text.x=element_text(size=12),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        plot.caption = element_text(face = "italic", size = 9),
        legend.position = "right") +
 geom_signif(y_position=c(1.1), xmin=c(1.1), xmax=c(1.9),
             annotation=c("***"), tip_length=0.1,
             vjust = 0, textsize = 4)
main_treatment_effect

ggsave(here("output", "figures", "main_treatment_effect.pdf"), main_treatment_effect, device="pdf", dpi=300,
       width = 15, height = 10, units = "cm")

ggsave(here("output", "figures", "main_treatment_effect.jpg"), main_treatment_effect, device="jpg", dpi=300,
       width = 15, height = 10, units = "cm")

rm(chi_table, chi_supply, MWW_supply, main_treatment_effect)

Figure 2: Predicted probability of expected supply by trust in government and treatment

library(effects)

oprob1 <- glm(supply_more ~ treatment * trust_govt, family = binomial(link = "probit"), data = df)

effect_trust <- as.data.frame(effect('treatment * trust_govt', oprob1, se = TRUE))
plot_trust <- ggplot(data=effect_trust, aes(x=trust_govt, y=fit, group=treatment))+
    geom_line(size=2, aes(color=treatment))+
    geom_ribbon(aes(ymin=fit-se, ymax=fit+se,fill=treatment),alpha=.2)+
    ylab("Predicted probability of expected supply")+
    xlab("The Dutch Government can be trusted")+
    theme_bw()+
    theme(text = element_text(size=12),
        legend.text = element_text(size=12),
        legend.direction = "horizontal",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        legend.position="top") +
  scale_x_continuous(breaks = c(1:5), labels = c("Strongly\n disagree", "Disagree", "Neutral", "Agree", "Strongly\n agree")) +
  scale_y_continuous(breaks = c(seq(0,0.6,0.1)), limits = c(0,0.65))
plot_trust

plot_trust <- annotate_figure(plot_trust,
                bottom = text_grob("\nNote: Based on Model 2 of Table 2.", color = "black",
                                  x = 0, just = "left", face = "italic", size = 8))

ggsave(here("output", "figures", "interaction_plot_trust.pdf"), plot_trust, device="pdf", dpi=300,
       width = 15, height = 15, units = "cm")
ggsave(here("output", "figures", "interaction_plot_trust.jpg"), plot_trust, device="jpg", dpi=300,
       width = 15, height = 15, units = "cm")

Figure 3: Predicted probabilities of supplying more on platforms in the coming two years, by treatment

effect_gender <- as.data.frame(effect('treatment * gender_f', oprob2, se = TRUE)) %>% 
  filter(gender_f == 0 | gender_f == 1)

plot_gender <- ggplot(data=effect_gender, aes(x=gender_f, y=fit, group=treatment))+
    geom_line(size=0.5, aes(color=treatment)) +
    geom_point(size=3, aes(color=treatment))+
    geom_errorbar(aes(ymin=fit-se, ymax=fit+se, color = treatment), width=.03, size = 1) +
    ylab("Predicted probability of supplying more")+
    xlab("Gender")+
    theme_bw()+
    theme(text = element_text(size=12),
        legend.text = element_text(size=12),
        legend.direction = "horizontal",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        legend.position="none") + scale_x_continuous(breaks = c(0, 1), labels = c("Male", "Female")) +
  scale_y_continuous(breaks = c(seq(0,0.6,0.1)), limits = c(0,0.65))


effect_hours <- as.data.frame(effect('treatment * hours_platform', oprob3, se = TRUE))
plot_hours<-ggplot(data=effect_hours, aes(x=hours_platform, y=fit, group=treatment))+
    geom_line(size=2, aes(color=treatment))+
    geom_ribbon(aes(ymin=fit-se, ymax=fit+se,fill=treatment),alpha=.2)+
    ylab("Predicted probability of supplying more")+
    xlab("Hours/week currently via platform")+
    theme_bw()+
    theme(text = element_text(size=12),
        legend.text = element_text(size=12),
        legend.direction = "horizontal",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        legend.position="right")  +
  scale_x_continuous(breaks = c(seq(0,60,10))) +
  scale_y_continuous(breaks = c(seq(0,0.6,0.1)), limits = c(0,0.65))

library(ggpubr)
interaction_plots <- ggarrange(plot_gender, plot_hours, nrow=1, common.legend = TRUE)
interaction_plots <- annotate_figure(interaction_plots,
                bottom = text_grob("\nNote: Left panel based on Model 2 of Table 3, right panel based on Model 5 of Table 3.", color = "black",
                                  x = 0, just = "left", face = "italic", size = 8))
interaction_plots

ggsave(here("output", "figures", "interaction_plots.pdf"), interaction_plots, device="pdf", dpi=300,
       width = 20, height = 10, units = "cm")
ggsave(here("output", "figures", "interaction_plots.jpg"), interaction_plots, device="jpg", dpi=300,
       width = 20, height = 10, units = "cm")

In-text statistics

reg_easy_pct <- round((addmargins(table(df$regulation_easy))["1"]/addmargins(table(df$regulation_easy))["Sum"])*100,1)
reg_fair_pct <- round((addmargins(table(df$regulation_fair))["1"]/addmargins(table(df$regulation_easy))["Sum"])*100,1)
reg_moretax_pct <- round((addmargins(table(df$regulation_more_tax))["1"]/addmargins(table(df$regulation_easy))["Sum"])*100,1)
reg_unnecesary_pct <- round((addmargins(table(df$regulation_unnecessary))["1"]/addmargins(table(df$regulation_easy))["Sum"])*100,1)
reg_other_pct <- round((addmargins(table(df$regulation_other))["1"]/addmargins(table(df$regulation_easy))["Sum"])*100,1)

df <- df %>% 
  mutate(reg_pos_neg = case_when(regulation_easy == 1 & regulation_fair == 1 ~ "2 positive",
                                 regulation_unnecessary == 1 & regulation_more_tax == 1 ~ "2 negative",
                                 (regulation_easy == 1 | regulation_fair == 1) & (regulation_more_tax == 1 | regulation_unnecessary == 1) ~ "1 of both",
                                 (regulation_easy == 1 | regulation_fair == 1) & regulation_more_tax == 0 & regulation_unnecessary == 0 ~ "1 positive",
                                 (regulation_more_tax == 1 | regulation_unnecessary == 1) & regulation_easy == 0 & regulation_fair == 0 ~ "1 negative"),
         reg_pos_neg = ordered(reg_pos_neg, levels = rev(c("2 positive", "1 positive", "1 of both", "1 negative", "2 negative"))),
         reg_pos_neg_num = as.numeric(reg_pos_neg), # higher number indicates more positive
         supply_num = as.numeric(supply))   # higher number indicating working more

reg_2pos <-  round((addmargins(table(df$reg_pos_neg))["2 positive"]/addmargins(table(df$reg_pos_neg))["Sum"])*100,0)
reg_1pos <-  round((addmargins(table(df$reg_pos_neg))["1 positive"]/addmargins(table(df$reg_pos_neg))["Sum"])*100,0)
reg_both <-  round((addmargins(table(df$reg_pos_neg))["1 of both"]/addmargins(table(df$reg_pos_neg))["Sum"])*100,0)
reg_1neg <-  round((addmargins(table(df$reg_pos_neg))["1 negative"]/addmargins(table(df$reg_pos_neg))["Sum"])*100,0)
reg_2neg <-  round((addmargins(table(df$reg_pos_neg))["2 negative"]/addmargins(table(df$reg_pos_neg))["Sum"])*100,0)

correlation <- round(cor(df$reg_pos_neg_num, df$supply_num, method = "spearman", use = "pairwise.complete.obs"),2)

In the information treatment, participants were asked “What do you think most gig workers think of this? (multiple answers possible)”

  • 16.9% answered “Not necessary, I can handle this myself”
  • 9.9% answered “Annoying, now I need to pay more taxes”
  • 24.8% answered “Great, this saves quite some administrative work”
  • 10.5% answered “Fair, this way all gig workers are taxed equally”
  • 1.6% answered “Other, namely:”

Since respondents could select multiple answers, we can examine whether whether positive answers outweigh negative answers or vice versa. When coding unnecessary and annoying as negative and saving admin work and fair as positive, we find 11% with two positive answers, 42% with one positive answer, 7% selecting a positive and a negative one, 34% selecting one negative answer and 6% selecting two negative answers.

The Spearman correlation between the number of positive versus negative selected opinions and the numeric version of the supply variable is very low (0.06).

regulation_opinion_other
Vervelend, want ik werk onregelmatig dus misschien betaal ik teveel belasting
Het is zeker makkelijker om te weten waar al het verdiende geld naartoe gaat vanuit <U+00E9><U+00E9>n centraal punt. Het verschil met loondienst en zzp zit hem in dat een zzp nog producten kan kopen (die voor zijn bedrijf nodig is) zonder btw wat weer wat geld overhoudt
Je bent in principe ondernemer en hoort het zelf doen erbij. Waar ligt dan nog de grens van ondernemer zijn en werknemer. Gezien de lag verdiensten, scheelt het wel werk. ik zou er geen problemen mee hebben.
Ik hou mijn inkomsten sowieso zelf ook bij. Maar dit voorkomt wel onzekerheid over wat wel in te vullen en wat niet.
It should be a choice. Either the platform does it or the people do it themselves . Also I think, the dutch government is financially not to trust so the less they are directly involved / have power over your finances the better. Rutte has to go.
Maakt me niks uit, belasting dienst komt er toch wel achter
maakt voor mij niet uit, want ik laat mijn IB aangifte altijd doen
Dit moet een optie zijn, niet standaard voor iedereen. persoonlijk zou ik het alleen willen als dat betekend dat het ENIGE dat ik hoef te doen is te checken of het klopt en mijn voorbelasting invullen zodat ik belastingaftrek heb. als ik nogsteeds zelf info moet invullen m.b.t. mijn inkomen kan de overheid het net zo goed niet weten.
Dan moet er wel een onderdeel zijn waar je je kosten ook kan invullen, want bij mij valt het nu onder werk uit overige werkzaamheden, omdat ik geen ondernemer voor de inkomstenbelasting ben, omdat ik nog niet aan het urencriterium kan doen.
Het helpt je te onthouden of je alle facturen in je belastingsaangifte hebt zitten en niks vergeet

Robustness checks

Table C1: Table 2 excluding incomplete responses

Footnote in Table 2: Model 2 (3) excludes 23 (2) subjects who answered Rather not say to the Trust in government (platforms) question. For robustness, we ran Models 1 and 2 without these subjects; the results do not change.

df2 <- df %>% 
  mutate(gender_f = case_when(gender == "Female" ~ 1, TRUE ~ 0)) %>% 
  filter(!is.na(trust_govt_dm)) %>% 
  filter(!is.na(trust_platforms_dm))

oprob1 <- polr(supply ~ treatment, data=df2, Hess=TRUE, method="probit")
oprob2 <- polr(supply ~ treatment * trust_govt_dm,  data=df2, Hess=TRUE, method="probit")
oprob3 <- polr(supply ~ treatment * trust_govt_dm + trust_platforms_dm + hours_platform + gender_f + age + only_income,  data=df2, Hess=TRUE, method="probit")
oprob4 <- polr(supply ~ treatment * trust_govt_dm + trust_platforms_dm + hours_platform + gender_f + age + only_income + self_report_know,  data=df2, Hess=TRUE, method="probit")

McFadden.oprob1 <- round(pR2(oprob1)["McFadden"],3)
LL.oprob1 <- round(pR2(oprob1)["llh"],1)
McFadden.oprob2 <- round(pR2(oprob2)["McFadden"],3)
LL.oprob2 <- round(pR2(oprob2)["llh"],1)
McFadden.oprob3 <- round(pR2(oprob3)["McFadden"],3)
LL.oprob3 <- round(pR2(oprob3)["llh"],1)
McFadden.oprob4 <- round(pR2(oprob4)["McFadden"],3)
LL.oprob4 <- round(pR2(oprob4)["llh"],1)

# cluster robust standard errors (for ordered probit you need CL)
coefs1 <- coeftest(oprob1, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust1 <- vcovCL(oprob1, type = "HC1") # HC1 reproduces STATA default
robust_se1    <- sqrt(diag(cov_robust1))
coefs2 <- coeftest(oprob2, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust2 <- vcovCL(oprob2, type = "HC1") # HC1 reproduces STATA default
robust_se2    <- sqrt(diag(cov_robust2))
coefs3 <- coeftest(oprob3, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust3 <- vcovCL(oprob3, type = "HC1") # HC1 reproduces STATA default
robust_se3    <- sqrt(diag(cov_robust3))
coefs4 <- coeftest(oprob4, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust4 <- vcovCL(oprob4, type = "HC1") # HC1 reproduces STATA default
robust_se4    <- sqrt(diag(cov_robust4))
#  text output in R markdown
stargazer(oprob1, oprob2, oprob3, oprob4,
          se = list(robust_se1, robust_se2, robust_se3, robust_se4),
          type = "html",
          keep.stat = c("rsq", "n"),
          intercept.bottom = FALSE,
          header=FALSE,
          title = "Ordered probit regressions of expected supply",
          covariate.labels = c("Information treatment (ref = Control)", "Information treatment X Trust in government",
                               "Trust in government", "Trust in platforms", "Hours/week working on platform", "Gender (1 = female)",
                               "Age", "Full-time platform work", "Self-reported tax knowledge"),
          order = c(1, 9, 2:8),
          model.names = FALSE,
          no.space = TRUE,
          dep.var.labels = "",
          dep.var.caption = "DV: expected supply",
          add.lines = list(c("Log likelihood", LL.oprob1, LL.oprob2, LL.oprob3, LL.oprob4),
                           c("Pseudo $R^2$ (McFadden)",
                             McFadden.oprob1, McFadden.oprob2, McFadden.oprob3, McFadden.oprob4)),
          star.cutoffs = c(0.05, 0.01, 0.001))
Ordered probit regressions of expected supply
DV: expected supply
(1) (2) (3) (4)
Information treatment (ref = Control) -0.551*** -0.552*** -0.552*** -0.560***
(0.096) (0.096) (0.097) (0.097)
Information treatment X Trust in government 0.057 0.055 0.042
(0.088) (0.089) (0.090)
Trust in government 0.041 0.023 0.017
(0.073) (0.074) (0.075)
Trust in platforms 0.004 -0.009
(0.062) (0.062)
Hours/week working on platform -0.004 -0.004
(0.006) (0.006)
Gender (1 = female) -0.105 -0.084
(0.101) (0.102)
Age -0.013 -0.014
(0.008) (0.008)
Full-time platform work 0.101 0.111
(0.109) (0.109)
Self-reported tax knowledge 0.091
(0.060)
Log likelihood -594.9 -593.5 -590.1 -588.8
Pseudo R(McFadden) 0.029 0.031 0.037 0.039
Observations 601 601 601 601
Note: p<0.05; p<0.01; p<0.001

Table C2: Table 2 with alternative trust variables

Text accompanying Table 2: As a robustness check, we conducted a similar analysis (ordered probit regression with interaction of treatment × trust) with the two alternative trust variables (Trust in platforms and General trust) where we find no significant interaction effects either.

# first de-mean trust
df <- df %>% 
  mutate(trust_govt_dm = scale(trust_govt, scale = F),
         trust_platforms_dm = scale(trust_platforms, scale = F),
         trust_others_dm = scale(trust_others, scale = F))

oprob1 <- polr(supply ~ treatment * trust_govt_dm, data=df, Hess=TRUE, method="probit")
oprob2 <- polr(supply ~ treatment * trust_platforms_dm, data=df, Hess=TRUE, method="probit")
oprob3 <- polr(supply ~ treatment * trust_others_dm, data=df, Hess=TRUE, method="probit")
McFadden.oprob1 <- round(pR2(oprob1)["McFadden"],3)
LL.oprob1 <- round(pR2(oprob1)["llh"],1)
McFadden.oprob2 <- round(pR2(oprob2)["McFadden"],3)
LL.oprob2 <- round(pR2(oprob2)["llh"],1)
McFadden.oprob3 <- round(pR2(oprob3)["McFadden"],3)
LL.oprob3 <- round(pR2(oprob3)["llh"],1)

# cluster robust standard errors (for ordered probit you need CL)
coefs1 <- coeftest(oprob1, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust1 <- vcovCL(oprob1, type = "HC1") # HC1 reproduces STATA default
robust_se1    <- sqrt(diag(cov_robust1))
coefs2 <- coeftest(oprob2, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust2 <- vcovCL(oprob2, type = "HC1") # HC1 reproduces STATA default
robust_se2    <- sqrt(diag(cov_robust2))
coefs3 <- coeftest(oprob3, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust3 <- vcovCL(oprob3, type = "HC1") # HC1 reproduces STATA default
robust_se3    <- sqrt(diag(cov_robust3))
#  text output in R markdown
stargazer(oprob1, oprob2, oprob3, 
          se = list(robust_se1, robust_se2, robust_se3),
          type = "html",
          keep.stat = c("rsq", "n"),
          intercept.bottom = FALSE,
          header=FALSE,
          title = "Ordered probit regressions of expected supply",
          covariate.labels = c("Information treatment (ref = Control)", "Information treatment X Trust in government",
                               "Information treatment X Trust in platforms", "Information treatment X General trust",
                               "Trust in government", "Trust in platforms", "General trust"),
          order = c(1, 3, 5, 7, 2, 4, 6),
          model.names = FALSE,
          no.space = TRUE,
          dep.var.labels = "",
          dep.var.caption = "DV: expected supply",
          add.lines = list(c("Log likelihood", LL.oprob1, LL.oprob2, LL.oprob3),
                           c("Pseudo $R^2$ (McFadden)",
                             McFadden.oprob1, McFadden.oprob2, McFadden.oprob3)),
          star.cutoffs = c(0.05, 0.01, 0.001))
Ordered probit regressions of expected supply
DV: expected supply
(1) (2) (3)
Information treatment (ref = Control) -0.549*** -0.549*** -0.536***
(0.096) (0.095) (0.095)
Information treatment X Trust in government 0.058
(0.087)
Information treatment X Trust in platforms -0.086
(0.116)
Information treatment X General trust -0.080
(0.104)
Trust in government 0.038
(0.072)
Trust in platforms 0.065
(0.099)
General trust 0.036
(0.084)
Log likelihood -594.9 -605.9 -601.6
Pseudo R(McFadden) 0.031 0.029 0.028
Observations 603 613 610
Note: p<0.05; p<0.01; p<0.001

Table C3: Table 2 with alternative full time dummy

df <- df %>% 
  mutate(full_time_40 = case_when(hours_platform > 39 ~ 1, TRUE ~ 0))

# first de-mean trust
df <- df %>% 
  mutate(trust_govt_dm = scale(trust_govt, scale = F),
         trust_platforms_dm = scale(trust_platforms, scale = F))

oprob1 <- polr(supply ~ treatment, data=df, Hess=TRUE, method="probit")
oprob2 <- polr(supply ~ treatment * trust_govt_dm,  data=df, Hess=TRUE, method="probit")
oprob3 <- polr(supply ~ treatment * trust_govt_dm + trust_platforms_dm + gender_f + age + full_time_40 + hours_platform,  data=df, Hess=TRUE, method="probit")
oprob4 <- polr(supply ~ treatment * trust_govt_dm + trust_platforms_dm + gender_f + age + full_time_40 + hours_platform + self_report_know,  data=df, Hess=TRUE, method="probit")

# could check interaction gender * treatment already now:
oprob5 <- polr(supply ~ treatment * gender_f + trust_govt_dm + trust_platforms_dm + age + full_time_40 + hours_platform,  data=df, Hess=TRUE, method="probit")
# could also check interaction hours_platform * treatment already now:
oprob6 <- polr(supply ~ treatment * hours_platform + gender_f + trust_govt_dm + trust_platforms_dm + age + full_time_40,  data=df, Hess=TRUE, method="probit")

McFadden.oprob1 <- round(pR2(oprob1)["McFadden"],3)
LL.oprob1 <- round(pR2(oprob1)["llh"],1)
McFadden.oprob2 <- round(pR2(oprob2)["McFadden"],3)
LL.oprob2 <- round(pR2(oprob2)["llh"],1)
McFadden.oprob3 <- round(pR2(oprob3)["McFadden"],3)
LL.oprob3 <- round(pR2(oprob3)["llh"],1)
McFadden.oprob4 <- round(pR2(oprob4)["McFadden"],3)
LL.oprob4 <- round(pR2(oprob4)["llh"],1)

# cluster robust standard errors (for ordered probit you need CL)
coefs1 <- coeftest(oprob1, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust1 <- vcovCL(oprob1, type = "HC1") # HC1 reproduces STATA default
robust_se1    <- sqrt(diag(cov_robust1))
coefs2 <- coeftest(oprob2, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust2 <- vcovCL(oprob2, type = "HC1") # HC1 reproduces STATA default
robust_se2    <- sqrt(diag(cov_robust2))
coefs3 <- coeftest(oprob3, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust3 <- vcovCL(oprob3, type = "HC1") # HC1 reproduces STATA default
robust_se3    <- sqrt(diag(cov_robust3))
coefs4 <- coeftest(oprob4, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust4 <- vcovCL(oprob4, type = "HC1") # HC1 reproduces STATA default
robust_se4    <- sqrt(diag(cov_robust4))
#  text output in R markdown
stargazer(oprob1, oprob2, oprob3, oprob4,
          se = list(robust_se1, robust_se2, robust_se3, robust_se4
                    ),
          type = "html",
          keep.stat = c("rsq", "n"),
          intercept.bottom = FALSE,
          header=FALSE,
          title = "Ordered probit regressions of expected supply",
          covariate.labels = c("Information treatment (ref = Control)", "Information treatment X Trust in government",
                               "Trust in government", "Trust in platforms",  "Gender (1 = female)",
                               "Age", "Full-time platform work" ,"Hours/week working on platform", "Self-reported tax knowledge"),
          order = c(1, 9, 2:8),
          model.names = FALSE,
          no.space = TRUE,
          dep.var.labels = "",
          dep.var.caption = "DV: expected supply",
          add.lines = list(c("Log likelihood", LL.oprob1, LL.oprob2, LL.oprob3, LL.oprob4
                             ),
                           c("Pseudo $R^2$ (McFadden)",
                             McFadden.oprob1, McFadden.oprob2, McFadden.oprob3, McFadden.oprob4
                             )),
          star.cutoffs = c(0.05, 0.01, 0.001))
Ordered probit regressions of expected supply
DV: expected supply
(1) (2) (3) (4)
Information treatment (ref = Control) -0.537*** -0.549*** -0.564*** -0.572***
(0.094) (0.096) (0.096) (0.097)
Information treatment X Trust in government 0.058 0.067 0.055
(0.087) (0.090) (0.090)
Trust in government 0.038 0.016 0.010
(0.072) (0.075) (0.076)
Trust in platforms 0.005 -0.007
(0.062) (0.063)
Gender (1 = female) -0.094 -0.074
(0.101) (0.102)
Age -0.014 -0.014
(0.008) (0.008)
Full-time platform work -0.489 -0.480
(0.348) (0.351)
Hours/week working on platform 0.004 0.003
(0.007) (0.007)
Self-reported tax knowledge 0.086
(0.061)
Log likelihood -618.2 -594.9 -589.3 -588.1
Pseudo R(McFadden) 0.028 0.031 0.038 0.04
Observations 626 603 601 601
Note: p<0.05; p<0.01; p<0.001

Table C4: Table 2 with linear model (OLS)

df <- df %>% 
  mutate(supply_num = case_when(supply == "Less" ~ -1,
                                supply == "Same" ~ 0,
                                supply == "More" ~ 1))
m0 <- lm(supply_num ~ treatment, data = df)
m1 <- lm(supply_num ~ treatment * trust_govt, data = df)
m2 <- lm(supply_num ~ treatment * trust_govt + trust_platforms + gender_f + age + only_income + hours_platform, data = df)
m3 <- lm(supply_num ~ treatment * trust_govt + trust_platforms + gender_f + age + only_income + hours_platform + self_report_know, data = df)
#  text output in R markdown
stargazer(m0, m1, m2, m3, type = "html", 
          keep.stat = c("rsq", "n"),
          intercept.bottom = FALSE,
          header=FALSE,
          title = "Linear regressions of expected supply",
          covariate.labels = c("Constant", "Information treatment (ref = Control)", "Information treatment X Trust in government",
                               "Trust in government", "Trust in platforms",  "Gender (1 = female)",
                               "Age", "Full-time platform work" ,"Hours/week working on platform", "Self-reported tax knowledge"),
          order = c(1, 2, 10, 3:9),
          model.names = FALSE,
          no.space = TRUE,
          dep.var.labels = "",
          dep.var.caption = "DV: expected supply",
          star.cutoffs = c(0.05, 0.01, 0.001))
Linear regressions of expected supply
DV: expected supply
(1) (2) (3) (4)
Constant 0.310*** 0.223 0.439* 0.286
(0.038) (0.133) (0.191) (0.213)
Information treatment (ref = Control) -0.319*** -0.458* -0.450* -0.426*
(0.054) (0.187) (0.189) (0.189)
Information treatment X Trust in government 0.038 0.036 0.028
(0.053) (0.053) (0.053)
Trust in government 0.022 0.013 0.010
(0.037) (0.039) (0.039)
Trust in platforms 0.002 -0.006
(0.037) (0.038)
Gender (1 = female) -0.064 -0.051
(0.059) (0.060)
Age -0.008 -0.008
(0.004) (0.004)
Full-time platform work 0.062 0.068
(0.063) (0.063)
Hours/week working on platform -0.002 -0.002
(0.003) (0.003)
Self-reported tax knowledge 0.055
(0.034)
Observations 626 603 601 601
R2 0.054 0.061 0.072 0.076
Note: p<0.05; p<0.01; p<0.001

Table C5: Table 3 with alternative full_time dummy

df <- df %>% 
  mutate(supply_more = case_when(supply == "More" ~ 1, TRUE ~ 0),
         student = case_when(occupation == "Student" ~ 1, TRUE ~ 0),
         full_time_40 = case_when(hours_platform > 39 ~ 1, TRUE ~ 0))

oprob1 <- glm(supply_more ~ treatment, family = binomial(link = "probit"), data = df)
oprob2 <- glm(supply_more ~ treatment * gender_f, family = binomial(link = "probit"), data = df)
oprob3 <- glm(supply_more ~ treatment * hours_platform, family = binomial(link = "probit"), data = df)
oprob4 <- glm(supply_more ~ treatment * age, family = binomial(link = "probit"), data = df)
oprob5 <- glm(supply_more ~ treatment * full_time_40, family = binomial(link = "probit"), data = df)
oprob_unused <- glm(supply_more ~ treatment * income_num, family = binomial(link = "probit"), data = df)

oprob6 <- glm(supply_more ~ treatment * gender_f + treatment*hours_platform + treatment*age +
                treatment*full_time_40 + treatment*self_report_know, family = binomial(link = "probit"), data = df)

oprob7 <- glm(supply_more ~ treatment * self_report_know, family = binomial(link = "probit"), data = df)

McFadden.oprob1 <- round(pR2(oprob1)["McFadden"],3)
LL.oprob1 <- round(pR2(oprob1)["llh"],1)
McFadden.oprob2 <- round(pR2(oprob2)["McFadden"],3)
LL.oprob2 <- round(pR2(oprob2)["llh"],1)
McFadden.oprob3 <- round(pR2(oprob3)["McFadden"],3)
LL.oprob3 <- round(pR2(oprob3)["llh"],1)
McFadden.oprob4 <- round(pR2(oprob4)["McFadden"],3)
LL.oprob4 <- round(pR2(oprob4)["llh"],1)
McFadden.oprob5 <- round(pR2(oprob5)["McFadden"],3)
LL.oprob5 <- round(pR2(oprob5)["llh"],1)
McFadden.oprob6 <- round(pR2(oprob6)["McFadden"],3)
LL.oprob6 <- round(pR2(oprob6)["llh"],1)
McFadden.oprob7 <- round(pR2(oprob7)["McFadden"],3)
LL.oprob7 <- round(pR2(oprob7)["llh"],1)


# cluster robust standard errors (for ordered probit you need CL)
coefs1 <- coeftest(oprob1, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust1 <- vcovCL(oprob1, type = "HC1") # HC1 reproduces STATA default
robust_se1    <- sqrt(diag(cov_robust1))
coefs2 <- coeftest(oprob2, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust2 <- vcovCL(oprob2, type = "HC1") # HC1 reproduces STATA default
robust_se2    <- sqrt(diag(cov_robust2))
coefs3 <- coeftest(oprob3, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust3 <- vcovCL(oprob3, type = "HC1") # HC1 reproduces STATA default
robust_se3    <- sqrt(diag(cov_robust3))
coefs4 <- coeftest(oprob4, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust4 <- vcovCL(oprob4, type = "HC1") # HC1 reproduces STATA default
robust_se4   <- sqrt(diag(cov_robust4))
coefs5 <- coeftest(oprob5, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust5 <- vcovCL(oprob5, type = "HC1") # HC1 reproduces STATA default
robust_se5    <- sqrt(diag(cov_robust5))
coefs6 <- coeftest(oprob6, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust6 <- vcovCL(oprob6, type = "HC1") # HC1 reproduces STATA default
robust_se6    <- sqrt(diag(cov_robust6))
coefs7 <- coeftest(oprob7, vcov = sandwich) # [1,1] is coefficient [1,4] is p-value
cov_robust7 <- vcovCL(oprob7, type = "HC1") # HC1 reproduces STATA default
robust_se7    <- sqrt(diag(cov_robust7))
#  text output in R markdown
stargazer(oprob1, oprob2, oprob4, oprob5, oprob3, oprob7, oprob6,
          se = list(robust_se1, robust_se2, robust_se4, robust_se5, robust_se3, robust_se7, robust_se6),
          type = "html",
          keep.stat = c("rsq", "n"),
          intercept.bottom = FALSE,
          header=FALSE,
          title = "Probit regressions of binary expected supply (1 = More)",
          covariate.labels = c("Constant", "Information (ref = Control)",
                               "Gender (1 = female)", "Information X Female",
                               "Age", "Information X Age",
                               "Full-time platform work", "Information X Full-time platform work",
                               "Hours/week working on platform", "Information X Hours/w working on platform",
                               "Self-reported tax knowledge", "Information X Self-reported tax knowledge"),
          model.names = FALSE,
          no.space = TRUE,
          dep.var.labels = "",
          dep.var.caption = "DV: expect to supply more",
          add.lines = list(c("Log likelihood", LL.oprob1, LL.oprob2, LL.oprob4, LL.oprob5, LL.oprob3, LL.oprob7, LL.oprob6),
                           c("Pseudo $R^2$ (McFadden)",
                             McFadden.oprob1, McFadden.oprob2, McFadden.oprob4, McFadden.oprob5, McFadden.oprob3, McFadden.oprob7, McFadden.oprob6)),
          star.cutoffs = c(0.05, 0.01, 0.001))
Probit regressions of binary expected supply (1 = More)
DV: expect to supply more
(1) (2) (3) (4) (5) (6) (7)
Constant -0.012 -0.031 0.460 0.021 0.111 -0.223 0.143
(0.071) (0.088) (0.269) (0.072) (0.109) (0.317) (0.450)
Information (ref = Control) -1.010*** -0.858*** -1.566*** -1.072*** -1.436*** -1.141* -1.551*
(0.112) (0.133) (0.396) (0.115) (0.182) (0.530) (0.647)
Gender (1 = female) 0.054 0.087
(0.149) (0.154)
Information X Female -0.564* -0.522
(0.256) (0.269)
Age -0.022 -0.019
(0.012) (0.012)
Information X Age 0.026 0.017
(0.018) (0.018)
Full-time platform work -0.988* -0.928
(0.438) (0.559)
Information X Full-time platform work 1.537** 0.731
(0.577) (0.758)
Hours/week working on platform -0.011 0.002
(0.007) (0.010)
Information X Hours/w working on platform 0.034** 0.022
(0.011) (0.015)
Self-reported tax knowledge 0.058 0.063
(0.086) (0.091)
Information X Self-reported tax knowledge 0.033 -0.004
(0.140) (0.140)
Log likelihood -351.1 -347.8 -349.1 -347.1 -345.8 -350.4 -339.5
Pseudo R(McFadden) 0.11 0.118 0.115 0.12 0.123 0.112 0.139
Observations 626 626 626 626 626 626 626
Note: p<0.05; p<0.01; p<0.001

Table C6: Table 3 with linear model (OLS)

df <- df %>% 
  mutate(supply_more = case_when(supply == "More" ~ 1, TRUE ~ 0),
         student = case_when(occupation == "Student" ~ 1, TRUE ~ 0))

m1 <- lm(supply_more ~ treatment, data = df)
m2 <- lm(supply_more ~ treatment * gender_f, data = df)
m3 <- lm(supply_more ~ treatment * hours_platform, data = df)
m4 <- lm(supply_more ~ treatment * age, data = df)
m5 <- lm(supply_more ~ treatment * only_income, data = df)
m6 <- lm(supply_more ~ treatment * gender_f + treatment*hours_platform + treatment*age +
                treatment*only_income + treatment*self_report_know, data = df)
m7 <- lm(supply_more ~ treatment * self_report_know, data = df)
#  text output in R markdown
stargazer(m1, m2, m4, m5, m3, m7, m6,
          type = "html",
          keep.stat = c("rsq", "n"),
          intercept.bottom = FALSE,
          header=FALSE,
          title = "OLS regressions of binary expected supply (1 = More)",
          covariate.labels = c("Constant", "Information (ref = Control)",
                               "Gender (1 = female)", "Information X Female",
                               "Age", "Information X Age",
                               "Full-time platform work", "Information X Full-time platform work",
                               "Hours/week working on platform", "Information X Hours/w working on platform",
                               "Self-reported tax knowledge", "Information X Self-reported tax knowledge"),
          model.names = FALSE,
          no.space = TRUE,
          dep.var.labels = "",
          dep.var.caption = "DV: expect to supply more",
          star.cutoffs = c(0.05, 0.01, 0.001))
OLS regressions of binary expected supply (1 = More)
DV: expect to supply more
(1) (2) (3) (4) (5) (6) (7)
Constant 0.495*** 0.488*** 0.679*** 0.493*** 0.544*** 0.412*** 0.586***
(0.025) (0.031) (0.085) (0.029) (0.038) (0.111) (0.145)
Information (ref = Control) -0.342*** -0.301*** -0.547*** -0.365*** -0.465*** -0.338* -0.549**
(0.035) (0.043) (0.116) (0.041) (0.054) (0.153) (0.192)
Gender (1 = female) 0.021 0.028
(0.052) (0.053)
Information X Female -0.128 -0.112
(0.074) (0.076)
Age -0.008* -0.008
(0.004) (0.004)
Information X Age 0.009 0.008
(0.005) (0.005)
Full-time platform work 0.007 0.016
(0.054) (0.055)
Information X Full-time platform work 0.086 0.040
(0.077) (0.079)
Hours/week working on platform -0.004 -0.004
(0.003) (0.003)
Information X Hours/w working on platform 0.010** 0.008*
(0.004) (0.004)
Self-reported tax knowledge 0.023 0.027
(0.030) (0.030)
Information X Self-reported tax knowledge -0.002 -0.011
(0.041) (0.041)
Observations 626 626 626 626 626 626 626
R2 0.133 0.139 0.140 0.137 0.146 0.135 0.159
Note: p<0.05; p<0.01; p<0.001

Session info

sessionInfo()
## R version 4.0.3 (2020-10-10)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 22621)
## 
## Matrix products: default
## 
## locale:
## [1] LC_COLLATE=English_Netherlands.65001  LC_CTYPE=C                           
## [3] LC_MONETARY=English_Netherlands.65001 LC_NUMERIC=C                         
## [5] LC_TIME=English_Netherlands.65001    
## system code page: 65001
## 
## attached base packages:
## [1] grid      stats     graphics  grDevices utils     datasets  methods  
## [8] base     
## 
## other attached packages:
##  [1] effects_4.2-1      carData_3.0-4      lmtest_0.9-38      zoo_1.8-8         
##  [5] sandwich_3.0-0     pscl_1.5.5         multiwayvcov_1.2.3 MASS_7.3-53       
##  [9] ggpubr_0.4.0       table1_1.2.1       ggsignif_0.6.0     scales_1.1.1      
## [13] gridExtra_2.3      ggrepel_0.9.1      knitr_1.30         readxl_1.3.1      
## [17] here_1.0.1         stargazer_5.2.2    forcats_0.5.0      stringr_1.4.0     
## [21] dplyr_1.0.2        purrr_0.3.4        readr_1.4.0        tidyr_1.1.2       
## [25] tibble_3.0.4       ggplot2_3.3.3      tidyverse_1.3.0   
## 
## loaded via a namespace (and not attached):
##  [1] nlme_3.1-149       fs_1.5.2           lubridate_1.7.9.2  insight_0.16.0    
##  [5] RColorBrewer_1.1-2 httr_1.4.2         rprojroot_2.0.2    tools_4.0.3       
##  [9] backports_1.2.0    bslib_0.3.1        utf8_1.1.4         R6_2.5.0          
## [13] DBI_1.1.1          colorspace_2.0-0   nnet_7.3-14        withr_2.5.0       
## [17] tidyselect_1.1.0   curl_4.3           compiler_4.0.3     cli_3.2.0         
## [21] rvest_0.3.6        xml2_1.3.2         sass_0.4.0         digest_0.6.27     
## [25] minqa_1.2.4        foreign_0.8-80     rmarkdown_2.11     rio_0.5.16        
## [29] pkgconfig_2.0.3    htmltools_0.5.2    lme4_1.1-26        highr_0.8         
## [33] dbplyr_2.0.0       fastmap_1.1.0      rlang_0.4.10       rstudioapi_0.13   
## [37] farver_2.0.3       jquerylib_0.1.4    generics_0.1.0     jsonlite_1.7.2    
## [41] zip_2.1.1          car_3.0-10         magrittr_2.0.1     Formula_1.2-4     
## [45] Matrix_1.2-18      Rcpp_1.0.5         munsell_0.5.0      fansi_0.4.1       
## [49] abind_1.4-5        lifecycle_1.0.1    stringi_1.5.3      yaml_2.2.1        
## [53] parallel_4.0.3     crayon_1.3.4       lattice_0.20-41    cowplot_1.1.1     
## [57] splines_4.0.3      haven_2.4.3        hms_1.0.0          pillar_1.6.4      
## [61] boot_1.3-25        estimability_1.3   reprex_0.3.0       glue_1.4.2        
## [65] evaluate_0.14      mitools_2.4        data.table_1.13.6  modelr_0.1.8      
## [69] nloptr_1.2.2.2     vctrs_0.3.8        cellranger_1.1.0   gtable_0.3.0      
## [73] assertthat_0.2.1   xfun_0.29          openxlsx_4.2.3     broom_1.0.4       
## [77] survey_4.0         rstatix_0.6.0      survival_3.2-7     statmod_1.4.35    
## [81] ellipsis_0.3.2