# Libraries
pacman::p_load(estimatr, texreg, janitor, tidyverse, skimr, compareGroups, BFpack, haven)
# Filter coefficients that start with "fac_active"
custom_screen <- function(model) {
  coef_names <- names(coef(model))
  keep <- grepl("^fac_active", coef_names)  # Matches coefficients starting with "fac_active"
  coef_list <- coef_names[keep]
  setNames(coef_list, coef_list)  # Named list where names match values
}

1 Experimental Sample

1.1 Table 3: Main effects

df <- 
  read_csv("data_experimental_sample_v2.csv") %>% 
  inner_join(read_csv("courseclassify.csv"), by = "course_name") %>% 
  filter(stem_indi == "STEM") %>% 
  left_join(read_dta(here::here("data/active_learning_new_constructs_india.dta")), by = "stdid") %>% 
  mutate(
    prior_knowledge_tercile = ntile(prior_knowledge, 3),
    stem_self_efficacy_tercile = ntile(stem_self_efficacy, 3),
    stem_anxiety_tercile = ntile(stem_anxiety, 3)
  )
lm1 <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  lm_robust(course_rank ~ fac_active_teaching, data = ., fixed_effects = ~ fe_var, se_type = "stata", clusters = facid)

lm2 <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  lm_robust(course_rank ~ fac_active_teaching + female + ses + reservation_stu + rural + father_college + mother_college, data = ., fixed_effects = ~ fe_var, se_type = "stata", clusters = facid)

lm3 <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  lm_robust(course_rank ~ fac_active_teaching, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm4 <-
  df %>% 
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  lm_robust(course_rank ~ fac_active_teaching + female + ses + reservation_stu + rural + father_college + mother_college + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ fe_var, se_type = "stata", clusters = facid)

lm5 <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

knitreg(list(lm1, lm2, lm3, lm4, lm5), custom.note = "%stars", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F)
  Model 1 Model 2 Model 3 Model 4 Model 5
fac_active_teaching -0.004 -0.007 -0.010 -0.006 -0.010
  (0.013) (0.013) (0.013) (0.013) (0.013)
female   0.427***   0.427***  
    (0.025)   (0.025)  
ses   0.037***   0.037***  
    (0.011)   (0.011)  
reservation_stu   -0.178***   -0.179***  
    (0.018)   (0.018)  
rural   -0.076***   -0.077***  
    (0.013)   (0.013)  
father_college   0.019   0.019  
    (0.014)   (0.014)  
mother_college   -0.032**   -0.031**  
    (0.014)   (0.014)  
fac_associate_professor       0.041 0.035
        (0.036) (0.034)
fac_professor       0.124* 0.063
        (0.065) (0.057)
fac_yearsinhighed       0.003 0.003
        (0.003) (0.002)
fac_highest_degree_phd       -0.089* -0.066
        (0.047) (0.047)
fac_highest_degree_phd_in_prog       -0.021 -0.055*
        (0.038) (0.030)
fac_degree_college_elite       0.012 0.022
        (0.025) (0.021)
fac_female       0.061** 0.050**
        (0.026) (0.023)
Num. obs. 33161 32248 33161 32032 32942
***p < 0.01; **p < 0.05; *p < 0.1

1.1.1 Bayes Factor

Model 1:

BF(
  x = coef(lm1),
  Sigma = vcov(lm1),
  n = nobs(lm1),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm1), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm1), n = nobs(lm1))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                     Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching  0.989  0.007  0.004
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.994
## H2               0.006
## 
## Evidence matrix (BFs):
##       H1     H2
## H1 1.000 174.22
## H2 0.006   1.00
## 
## Specification table:
##    complex= complex>   fit= fit>    BF= BF>           BF   PHP
## H1    0.169        1 29.403    1 174.22   1 4.599752e+75 0.994
## H2    1.000        1  1.000    1   1.00   1 2.718000e+00 0.006
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

Model 2:

BF(
  x = coef(lm2),
  Sigma = vcov(lm2),
  n = nobs(lm2),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm2), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm2), n = nobs(lm2))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                     Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching  0.987  0.009  0.004
## female               0.000  0.000  1.000
## ses                  0.180  0.000  0.820
## reservation_stu      0.000  1.000  0.000
## rural                0.000  1.000  0.000
## father_college       0.971  0.002  0.027
## mother_college       0.878  0.120  0.002
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.994
## H2               0.006
## 
## Evidence matrix (BFs):
##       H1      H2
## H1 1.000 157.038
## H2 0.006   1.000
## 
## Specification table:
##    complex= complex>   fit= fit>     BF= BF>           BF   PHP
## H1    0.173        1 27.114    1 157.038   1 1.587803e+68 0.994
## H2    1.000        1  1.000    1   1.000   1 2.718000e+00 0.006
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

Model 3:

BF(
  x = coef(lm3),
  Sigma = vcov(lm3),
  n = nobs(lm3),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm3), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm3), n = nobs(lm3))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                     Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching  0.985  0.011  0.003
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.993
## H2               0.007
## 
## Evidence matrix (BFs):
##       H1      H2
## H1 1.000 135.297
## H2 0.007   1.000
## 
## Specification table:
##    complex= complex>   fit= fit>     BF= BF>           BF   PHP
## H1    0.164        1 22.165    1 135.297   1 5.736206e+58 0.993
## H2    1.000        1  1.000    1   1.000   1 2.718000e+00 0.007
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

Model 4:

BF(
  x = coef(lm4),
  Sigma = vcov(lm4),
  n = nobs(lm4),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm4), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm4), n = nobs(lm4))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                                Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching             0.988  0.008  0.004
## female                          0.000  0.000  1.000
## ses                             0.223  0.000  0.777
## reservation_stu                 0.000  1.000  0.000
## rural                           0.000  1.000  0.000
## father_college                  0.972  0.002  0.026
## mother_college                  0.894  0.104  0.002
## fac_associate_professor         0.979  0.003  0.018
## fac_professor                   0.934  0.002  0.064
## fac_yearsinhighed               0.976  0.003  0.021
## fac_highest_degree_phd          0.939  0.059  0.002
## fac_highest_degree_phd_in_prog  0.987  0.009  0.004
## fac_degree_college_elite        0.988  0.004  0.008
## fac_female                      0.848  0.001  0.150
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.994
## H2               0.006
## 
## Evidence matrix (BFs):
##       H1      H2
## H1 1.000 159.691
## H2 0.006   1.000
## 
## Specification table:
##    complex= complex>   fit= fit>     BF= BF>           BF   PHP
## H1    0.171        1 27.387    1 159.691   1 2.253412e+69 0.994
## H2    1.000        1  1.000    1   1.000   1 2.718000e+00 0.006
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

Model 5:

BF(
  x = coef(lm5),
  Sigma = vcov(lm5),
  n = nobs(lm5),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm5), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm5), n = nobs(lm5))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                                Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching             0.986  0.011  0.003
## fac_associate_professor         0.982  0.003  0.016
## fac_professor                   0.980  0.003  0.017
## fac_yearsinhighed               0.973  0.002  0.025
## fac_highest_degree_phd          0.971  0.027  0.002
## fac_highest_degree_phd_in_prog  0.944  0.054  0.002
## fac_degree_college_elite        0.982  0.003  0.016
## fac_female                      0.899  0.002  0.100
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.993
## H2               0.007
## 
## Evidence matrix (BFs):
##       H1      H2
## H1 1.000 137.543
## H2 0.007   1.000
## 
## Specification table:
##    complex= complex>   fit= fit>     BF= BF>          BF   PHP
## H1    0.168        1 23.137    1 137.543   1 5.42399e+59 0.993
## H2    1.000        1  1.000    1   1.000   1 2.71800e+00 0.007
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

1.2 Table 4: Heterogeneous effects

lm1a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(female == 0) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm1b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(female == 1) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm2a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(ses_lowest_tercile == 0) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm2b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(ses_lowest_tercile == 1) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm3a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(math_lowest_tercile == 0) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm3b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(math_lowest_tercile == 1) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm4a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(rural == 0) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm4b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(rural == 1) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm5a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(reservation_stu == 0) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm5b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(reservation_stu == 1) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

knitreg(list(lm1a, lm1b, lm2a, lm2b, lm3a, lm3b, lm4a, lm4b, lm5a, lm5b), custom.note = "Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Low SES refers to a student being in the bottom tercile of the SES score taken from the first principal component of polychoric principal component analysis on equipment (e.g.~TV, microwave, car, computer) present at a student's home. High score refers to a student being in the top and middle terciles of this SES score. Standard errors are clustered at the faculty level. ***, **, and * indicate significance at 1%, 5%, and 10%.", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F, custom.coef.map = list("fac_active_teaching" = "Active learning"), custom.model.names = c("Male", "Female", "High/medium SES", "Low SES", "High math skills", "Low math skills", "Urban", "Rural", "Non-reservation", "Reservation"))
  Male Female High/medium SES Low SES High math skills Low math skills Urban Rural Non-reservation Reservation
Active learning 0.005 -0.024 -0.012 0.001 -0.006 0.038 0.006 -0.019 0.015 -0.029*
  (0.014) (0.017) (0.015) (0.017) (0.018) (0.025) (0.014) (0.017) (0.016) (0.016)
Num. obs. 17680 15228 20976 11514 10639 4911 17379 15187 15227 17671
Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Low SES refers to a student being in the bottom tercile of the SES score taken from the first principal component of polychoric principal component analysis on equipment (e.g.~TV, microwave, car, computer) present at a student’s home. High score refers to a student being in the top and middle terciles of this SES score. Standard errors are clustered at the faculty level. , , and indicate significance at 1%, 5%, and 10%.

1.2.1 Bayes Factor

Males:

BF(
  x = coef(lm1a),
  Sigma = vcov(lm1a),
  n = nobs(lm1a),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm1a), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm1a), n = nobs(lm1a))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                                Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching             0.984  0.006  0.010
## fac_associate_professor         0.980  0.004  0.016
## fac_professor                   0.824  0.002  0.174
## fac_yearsinhighed               0.985  0.006  0.009
## fac_highest_degree_phd          0.983  0.012  0.005
## fac_highest_degree_phd_in_prog  0.985  0.009  0.006
## fac_degree_college_elite        0.970  0.003  0.027
## fac_female                      0.982  0.005  0.013
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.992
## H2               0.008
## 
## Evidence matrix (BFs):
##       H1      H2
## H1 1.000 125.926
## H2 0.008   1.000
## 
## Specification table:
##    complex= complex>   fit= fit>     BF= BF>           BF   PHP
## H1    0.212        1 26.646    1 125.926   1 4.884092e+54 0.992
## H2    1.000        1  1.000    1   1.000   1 2.718000e+00 0.008
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

Females:

BF(
  x = coef(lm1b),
  Sigma = vcov(lm1b),
  n = nobs(lm1b),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm1b), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm1b), n = nobs(lm1b))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                                Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching             0.960  0.037  0.003
## fac_associate_professor         0.984  0.007  0.009
## fac_professor                   0.984  0.010  0.007
## fac_yearsinhighed               0.880  0.002  0.117
## fac_highest_degree_phd          0.972  0.024  0.004
## fac_highest_degree_phd_in_prog  0.765  0.233  0.002
## fac_degree_college_elite        0.977  0.004  0.019
## fac_female                      0.726  0.002  0.272
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.979
## H2               0.021
## 
## Evidence matrix (BFs):
##       H1     H2
## H1 1.000 47.776
## H2 0.021  1.000
## 
## Specification table:
##    complex= complex> fit= fit>    BF= BF>           BF   PHP
## H1    0.189        1 9.02    1 47.776   1 5.608048e+20 0.979
## H2    1.000        1 1.00    1  1.000   1 2.718000e+00 0.021
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

High/medium SES:

BF(
  x = coef(lm2a),
  Sigma = vcov(lm2a),
  n = nobs(lm2a),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm2a), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm2a), n = nobs(lm2a))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                                Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching             0.982  0.014  0.004
## fac_associate_professor         0.931  0.002  0.067
## fac_professor                   0.977  0.003  0.020
## fac_yearsinhighed               0.974  0.003  0.023
## fac_highest_degree_phd          0.973  0.024  0.003
## fac_highest_degree_phd_in_prog  0.920  0.078  0.002
## fac_degree_college_elite        0.985  0.005  0.010
## fac_female                      0.963  0.003  0.035
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.991
## H2               0.009
## 
## Evidence matrix (BFs):
##       H1      H2
## H1 1.000 108.266
## H2 0.009   1.000
## 
## Specification table:
##    complex= complex>   fit= fit>     BF= BF>           BF   PHP
## H1    0.178        1 19.316    1 108.266   1 1.045689e+47 0.991
## H2    1.000        1  1.000    1   1.000   1 2.718000e+00 0.009
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

Low SES:

BF(
  x = coef(lm2b),
  Sigma = vcov(lm2b),
  n = nobs(lm2b),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm2b), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm2b), n = nobs(lm2b))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                                Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching             0.982  0.009  0.009
## fac_associate_professor         0.982  0.010  0.008
## fac_professor                   0.979  0.006  0.014
## fac_yearsinhighed               0.976  0.005  0.018
## fac_highest_degree_phd          0.974  0.021  0.005
## fac_highest_degree_phd_in_prog  0.975  0.020  0.005
## fac_degree_college_elite        0.978  0.006  0.016
## fac_female                      0.883  0.003  0.115
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.991
## H2               0.009
## 
## Evidence matrix (BFs):
##       H1      H2
## H1 1.000 107.233
## H2 0.009   1.000
## 
## Specification table:
##    complex= complex>   fit= fit>     BF= BF>           BF   PHP
## H1    0.224        1 23.968    1 107.233   1 3.722303e+46 0.991
## H2    1.000        1  1.000    1   1.000   1 2.718000e+00 0.009
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

High math skill:

BF(
  x = coef(lm3a),
  Sigma = vcov(lm3a),
  n = nobs(lm3a),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm3a), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm3a), n = nobs(lm3a))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                                Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching             0.980  0.013  0.007
## fac_associate_professor         0.972  0.005  0.022
## fac_professor                   0.972  0.005  0.022
## fac_yearsinhighed               0.977  0.006  0.017
## fac_highest_degree_phd          0.975  0.019  0.006
## fac_highest_degree_phd_in_prog  0.977  0.017  0.006
## fac_degree_college_elite        0.980  0.008  0.012
## fac_female                      0.696  0.002  0.302
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1                0.99
## H2                0.01
## 
## Evidence matrix (BFs):
##      H1     H2
## H1 1.00 97.763
## H2 0.01  1.000
## 
## Specification table:
##    complex= complex>   fit= fit>    BF= BF>           BF  PHP
## H1    0.214        1 20.944    1 97.763   1 2.868917e+42 0.99
## H2    1.000        1  1.000    1  1.000   1 2.718000e+00 0.01
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

Low math skill:

BF(
  x = coef(lm3b),
  Sigma = vcov(lm3b),
  n = nobs(lm3b),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm3b), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm3b), n = nobs(lm3b))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                                Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching             0.920  0.005  0.075
## fac_associate_professor         0.934  0.006  0.060
## fac_professor                   0.959  0.008  0.033
## fac_yearsinhighed               0.971  0.011  0.018
## fac_highest_degree_phd          0.856  0.139  0.004
## fac_highest_degree_phd_in_prog  0.010  0.990  0.000
## fac_degree_college_elite        0.857  0.004  0.139
## fac_female                      0.923  0.006  0.071
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.958
## H2               0.042
## 
## Evidence matrix (BFs):
##       H1     H2
## H1 1.000 22.902
## H2 0.044  1.000
## 
## Specification table:
##    complex= complex>  fit= fit>    BF= BF>           BF   PHP
## H1    0.227        1 5.193    1 22.902   1 8.834554e+09 0.958
## H2    1.000        1 1.000    1  1.000   1 2.718000e+00 0.042
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

Urban:

BF(
  x = coef(lm4a),
  Sigma = vcov(lm4a),
  n = nobs(lm4a),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm4a), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm4a), n = nobs(lm4a))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                                Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching             0.984  0.005  0.011
## fac_associate_professor         0.985  0.009  0.006
## fac_professor                   0.976  0.004  0.020
## fac_yearsinhighed               0.968  0.003  0.028
## fac_highest_degree_phd          0.968  0.028  0.003
## fac_highest_degree_phd_in_prog  0.980  0.016  0.004
## fac_degree_college_elite        0.953  0.003  0.044
## fac_female                      0.969  0.003  0.028
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.992
## H2               0.008
## 
## Evidence matrix (BFs):
##       H1      H2
## H1 1.000 120.589
## H2 0.008   1.000
## 
## Specification table:
##    complex= complex>   fit= fit>     BF= BF>           BF   PHP
## H1    0.215        1 25.869    1 120.589   1 2.349536e+52 0.992
## H2    1.000        1  1.000    1   1.000   1 2.718000e+00 0.008
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

Rural:

BF(
  x = coef(lm4b),
  Sigma = vcov(lm4b),
  n = nobs(lm4b),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm4b), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm4b), n = nobs(lm4b))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                                Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching             0.970  0.026  0.004
## fac_associate_professor         0.926  0.003  0.072
## fac_professor                   0.978  0.005  0.017
## fac_yearsinhighed               0.972  0.004  0.024
## fac_highest_degree_phd          0.970  0.026  0.004
## fac_highest_degree_phd_in_prog  0.891  0.107  0.002
## fac_degree_college_elite        0.984  0.008  0.008
## fac_female                      0.742  0.002  0.256
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.985
## H2               0.015
## 
## Evidence matrix (BFs):
##       H1     H2
## H1 1.000 65.165
## H2 0.015  1.000
## 
## Specification table:
##    complex= complex>   fit= fit>    BF= BF>           BF   PHP
## H1    0.192        1 12.493    1 65.165   1 1.999432e+28 0.985
## H2    1.000        1  1.000    1  1.000   1 2.718000e+00 0.015
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

Non-reservation:

BF(
  x = coef(lm5a),
  Sigma = vcov(lm5a),
  n = nobs(lm5a),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm5a), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm5a), n = nobs(lm5a))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                                Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching             0.975  0.004  0.021
## fac_associate_professor         0.982  0.006  0.013
## fac_professor                   0.984  0.008  0.008
## fac_yearsinhighed               0.912  0.003  0.086
## fac_highest_degree_phd          0.984  0.010  0.007
## fac_highest_degree_phd_in_prog  0.804  0.194  0.002
## fac_degree_college_elite        0.984  0.007  0.010
## fac_female                      0.963  0.003  0.034
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.987
## H2               0.013
## 
## Evidence matrix (BFs):
##       H1     H2
## H1 1.000 77.182
## H2 0.013  1.000
## 
## Specification table:
##    complex= complex>   fit= fit>    BF= BF>           BF   PHP
## H1    0.204        1 15.708    1 77.182   1 3.309572e+33 0.987
## H2    1.000        1  1.000    1  1.000   1 2.718000e+00 0.013
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

Reservation:

BF(
  x = coef(lm5b),
  Sigma = vcov(lm5b),
  n = nobs(lm5b),
  hypothesis = "fac_active_teaching = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm5b), hypothesis = "fac_active_teaching = 0", 
##     Sigma = vcov(lm5b), n = nobs(lm5b))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                                Pr(=0) Pr(<0) Pr(>0)
## fac_active_teaching             0.932  0.066  0.003
## fac_associate_professor         0.981  0.005  0.014
## fac_professor                   0.955  0.003  0.042
## fac_yearsinhighed               0.982  0.005  0.013
## fac_highest_degree_phd          0.946  0.051  0.003
## fac_highest_degree_phd_in_prog  0.969  0.028  0.003
## fac_degree_college_elite        0.970  0.003  0.026
## fac_female                      0.887  0.002  0.111
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.965
## H2               0.035
## 
## Evidence matrix (BFs):
##       H1     H2
## H1 1.000 27.204
## H2 0.037  1.000
## 
## Specification table:
##    complex= complex>  fit= fit>    BF= BF>          BF   PHP
## H1    0.185        1 5.046    1 27.204   1 6.52304e+11 0.965
## H2    1.000        1 1.000    1  1.000   1 2.71800e+00 0.035
## 
## Hypotheses:
## H1: fac_active_teaching=0
## H2: complement

1.3 Heterogeneity for new constructs

All new constructs are z-scored (mean 0, sd 1) at the national sample level.

1.3.1 Check: Constructs as student-level outcomes

All variables are aggregated to the student-level. Both models include department fixed-effects.

df_stulevel <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  rename(b_stem_self_efficacy = stem_self_efficacy, b_stem_anxiety = stem_anxiety) %>% 
  group_by(stdid, department_id, e_stem_self_efficacy, b_stem_self_efficacy, e_stem_anxiety, b_stem_anxiety, female, reservation_stu, father_college, mother_college, ses_lowest_tercile) %>% 
  summarize(
    fac_active_teaching = mean(fac_active_teaching, na.rm = T),
    fac_associate_professor = mean(fac_associate_professor, na.rm = T),
    fac_professor = mean(fac_professor, na.rm = T),
    fac_yearsinhighed = mean(fac_yearsinhighed, na.rm = T),
    fac_highest_degree_phd = mean(fac_highest_degree_phd, na.rm = T),
    fac_highest_degree_phd_in_prog = mean(fac_highest_degree_phd_in_prog, na.rm = T),
    fac_degree_college_elite = mean(fac_degree_college_elite, na.rm = T),
    fac_female = mean(fac_female, na.rm = T),
  ) %>%
  ungroup() 

lm1 <-
  df_stulevel %>% 
  lm_robust(e_stem_anxiety ~ fac_active_teaching + b_stem_anxiety + female + reservation_stu + father_college + mother_college + ses_lowest_tercile + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ department_id, se_type = "stata") 

lm2 <-
  df_stulevel %>% 
  lm_robust(e_stem_self_efficacy ~ fac_active_teaching + b_stem_self_efficacy + female + reservation_stu + father_college + mother_college + ses_lowest_tercile + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ department_id, se_type = "stata")

rm(df_stulevel)

knitreg(list(lm1, lm2), custom.note = "%stars", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F, custom.model.names = c("Anxiety", "Self-efficacy"))
  Anxiety Self-efficacy
fac_active_teaching 0.111 -0.043
  (0.131) (0.124)
b_stem_anxiety 0.462***  
  (0.022)  
female -0.170*** 0.116***
  (0.049) (0.044)
reservation_stu 0.101** -0.051
  (0.042) (0.039)
father_college -0.034 -0.036
  (0.048) (0.044)
mother_college 0.045 -0.093**
  (0.051) (0.044)
ses_lowest_tercile 0.023 -0.009
  (0.045) (0.041)
fac_associate_professor 0.023 -0.524*
  (0.323) (0.311)
fac_professor -1.308** 0.697
  (0.566) (0.526)
fac_yearsinhighed 0.038 -0.074***
  (0.027) (0.024)
fac_highest_degree_phd 0.264 0.158
  (0.511) (0.466)
fac_highest_degree_phd_in_prog 0.020 -0.112
  (0.281) (0.257)
fac_degree_college_elite 0.047 0.237
  (0.339) (0.283)
fac_female 0.144 -0.127
  (0.247) (0.234)
b_stem_self_efficacy   0.546***
    (0.021)
Num. obs. 1873 1871
***p < 0.01; **p < 0.05; *p < 0.1

1.3.2 Based on means

In these models, scores above the mean (0) are considered high, scores equal to or below 0 are considered low.

1.3.2.1 Subsamples

lm1a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(stem_anxiety > mean(stem_anxiety, na.rm = T)) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm1b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(stem_anxiety <= mean(stem_anxiety, na.rm = T)) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm2a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(stem_self_efficacy > mean(stem_self_efficacy, na.rm = T)) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm2b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(stem_self_efficacy <= mean(stem_self_efficacy, na.rm = T)) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm3a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(prior_knowledge > mean(prior_knowledge, na.rm = T)) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm3b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(prior_knowledge <= mean(prior_knowledge, na.rm = T)) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

knitreg(list(lm1a, lm1b, lm2a, lm2b, lm3a, lm3b), custom.note = "Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. ***, **, and * indicate significance at 1%, 5%, and 10%.", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F, custom.coef.map = list("fac_active_teaching" = "Active learning"), custom.model.names = c("High STEM anxiety", "Low STEM anxiety", "High STEM self-efficacy", "Low STEM self-efficacy", "High prior knowledge", "Low prior knowledge"))
  High STEM anxiety Low STEM anxiety High STEM self-efficacy Low STEM self-efficacy High prior knowledge Low prior knowledge
Active learning -0.022 0.007 -0.006 -0.012 -0.017 0.001
  (0.018) (0.015) (0.015) (0.018) (0.015) (0.019)
Num. obs. 14668 15259 14667 15207 13001 17040
Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. , , and indicate significance at 1%, 5%, and 10%.

1.3.2.2 Interactions

lm1c <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(low_anxiety = (stem_anxiety <= mean(stem_anxiety, na.rm = T))) %>%
  lm_robust(course_rank ~ fac_active_teaching * low_anxiety + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ fe_var, se_type = "stata", clusters = facid)

lm2c <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(high_self_efficacy = (stem_self_efficacy > mean(stem_self_efficacy, na.rm = T))) %>%
  lm_robust(course_rank ~ fac_active_teaching * high_self_efficacy + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ fe_var, se_type = "stata", clusters = facid)

lm3c <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(high_prior_knowledge = (prior_knowledge > mean(prior_knowledge, na.rm = T))) %>%
  lm_robust(course_rank ~ fac_active_teaching * high_prior_knowledge + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ fe_var, se_type = "stata", clusters = facid)

knitreg(list(lm1c, lm2c, lm3c), custom.note = "Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. ***, **, and * indicate significance at 1%, 5%, and 10%.", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F, omit.coef = "(professor)|(highed)|(phd)|(elite)|(female)|(^high)", custom.model.names = c("Anxiety", "Self efficacy", "Prior knowledge"))
  Anxiety Self efficacy Prior knowledge
fac_active_teaching -0.004 0.010 0.006
  (0.019) (0.018) (0.018)
low_anxietyTRUE 0.399***    
  (0.019)    
fac_active_teaching:low_anxietyTRUE 0.007    
  (0.020)    
fac_active_teaching:high_self_efficacyTRUE   -0.020  
    (0.019)  
fac_active_teaching:high_prior_knowledgeTRUE     -0.016
      (0.021)
Num. obs. 29927 29874 30041
Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. , , and indicate significance at 1%, 5%, and 10%.

1.3.3 Based on median

High is defined as the above median, low is defined as the below median.

1.3.3.1 Subsamples

lm1a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(stem_anxiety > median(stem_anxiety, na.rm = T)) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm1b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(stem_anxiety <= median(stem_anxiety, na.rm = T)) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm2a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(stem_self_efficacy > median(stem_self_efficacy, na.rm = T)) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm2b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(stem_self_efficacy <= median(stem_self_efficacy, na.rm = T)) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm3a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(prior_knowledge > median(prior_knowledge, na.rm = T)) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm3b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(prior_knowledge <= median(prior_knowledge, na.rm = T)) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

knitreg(list(lm1a, lm1b, lm2a, lm2b, lm3a, lm3b), custom.note = "Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. ***, **, and * indicate significance at 1%, 5%, and 10%.", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F, custom.coef.map = list("fac_active_teaching" = "Active learning"), custom.model.names = c("High STEM anxiety", "Low STEM anxiety", "High STEM self-efficacy", "Low STEM self-efficacy", "High prior knowledge", "Low prior knowledge"))
  High STEM anxiety Low STEM anxiety High STEM self-efficacy Low STEM self-efficacy High prior knowledge Low prior knowledge
Active learning -0.022 0.007 -0.006 -0.012 -0.010 -0.002
  (0.018) (0.015) (0.015) (0.018) (0.014) (0.021)
Num. obs. 14678 15249 14886 14988 14946 15095
Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. , , and indicate significance at 1%, 5%, and 10%.

1.3.3.2 Interactions

lm1c <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(low_anxiety = (stem_anxiety <= median(stem_anxiety, na.rm = T))) %>%
  lm_robust(course_rank ~ fac_active_teaching * low_anxiety + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm2c <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(high_self_efficacy = (stem_self_efficacy > median(stem_self_efficacy, na.rm = T))) %>%
  lm_robust(course_rank ~ fac_active_teaching * high_self_efficacy + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm3c <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(high_prior_knowledge = (prior_knowledge > median(prior_knowledge, na.rm = T))) %>%
  lm_robust(course_rank ~ fac_active_teaching * high_prior_knowledge + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

knitreg(list(lm1c, lm2c, lm3c), custom.note = "Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. ***, **, and * indicate significance at 1%, 5%, and 10%.", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F, omit.coef = "(professor)|(highed)|(phd)|(elite)|(female)|(^high)", custom.model.names = c("Anxiety", "Self efficacy", "Prior knowledge"))
  Anxiety Self efficacy Prior knowledge
fac_active_teaching -0.007 0.012 0.000
  (0.016) (0.017) (0.017)
low_anxietyTRUE      
       
fac_active_teaching:low_anxietyTRUE -0.004    
  (0.016)    
fac_active_teaching:high_self_efficacyTRUE   -0.041***  
    (0.015)  
fac_active_teaching:high_prior_knowledgeTRUE     -0.015
      (0.014)
Num. obs. 29927 29874 30041
Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. , , and indicate significance at 1%, 5%, and 10%.

1.3.4 Based on terciles

High is defined as the highest tercile, low is defined as the lowest tercile.

1.3.4.1 Subsamples

lm1a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(stem_anxiety_tercile == 3) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm1b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(stem_anxiety_tercile == 1) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm2a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(stem_self_efficacy_tercile == 3) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm2b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(stem_self_efficacy_tercile == 1) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm3a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(prior_knowledge_tercile == 3) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm3b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  filter(prior_knowledge_tercile == 1) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

knitreg(list(lm1a, lm1b, lm2a, lm2b, lm3a, lm3b), custom.note = "Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. ***, **, and * indicate significance at 1%, 5%, and 10%.", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F, custom.coef.map = list("fac_active_teaching" = "Active learning"), custom.model.names = c("High STEM anxiety", "Low STEM anxiety", "High STEM self-efficacy", "Low STEM self-efficacy", "High prior knowledge", "Low prior knowledge"))
  High STEM anxiety Low STEM anxiety High STEM self-efficacy Low STEM self-efficacy High prior knowledge Low prior knowledge
Active learning 0.006 0.008 0.012 -0.026 -0.001 0.020
  (0.022) (0.018) (0.016) (0.023) (0.017) (0.021)
Num. obs. 9985 9945 9936 9978 9996 10042
Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. , , and indicate significance at 1%, 5%, and 10%.

1.3.4.2 Interactions

lm1c <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(low_anxiety = (stem_anxiety_tercile == 1)) %>%
  lm_robust(course_rank ~ fac_active_teaching * low_anxiety + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm2c <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(high_self_efficacy = (stem_self_efficacy_tercile == 3)) %>%
  lm_robust(course_rank ~ fac_active_teaching * high_self_efficacy + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm3c <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(high_prior_knowledge = (prior_knowledge_tercile == 3)) %>%
  lm_robust(course_rank ~ fac_active_teaching * high_prior_knowledge + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

knitreg(list(lm1c, lm2c, lm3c), custom.note = "Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. ***, **, and * indicate significance at 1%, 5%, and 10%.", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F, omit.coef = "(professor)|(highed)|(phd)|(elite)|(female)|(^high)|(^low)", custom.model.names = c("Anxiety", "Self efficacy", "Prior knowledge"))
  Anxiety Self efficacy Prior knowledge
fac_active_teaching -0.007 -0.001 -0.008
  (0.015) (0.015) (0.015)
fac_active_teaching:low_anxietyTRUE -0.005    
  (0.016)    
fac_active_teaching:high_self_efficacyTRUE   -0.021  
    (0.016)  
fac_active_teaching:high_prior_knowledgeTRUE     -0.000
      (0.014)
Num. obs. 29927 29874 30041
Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. , , and indicate significance at 1%, 5%, and 10%.
# rough tests

df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(high_prior_knowledge = (prior_knowledge_tercile == 3)) %>% 
  select(stdid, contains("prior")) %>%
  filter(stdid == "IR045EE1024") %>% view()
  distinct(stdid, high_prior_knowledge, prior_knowledge) %>%
  filter(stdid == "IR045EE1024")
  count(stdid) %>% arrange(-n)

1.3.5 Low anxiety High self-effiacy High prior knowledge

Model 1 sample is Low anxiety + High self-efficacy + High prior knowledge.

Model 2 sample is complement of that.

1.3.5.1 Based on medians

lm1a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(flag = (stem_anxiety <= median(stem_anxiety, na.rm = T)) & (stem_self_efficacy > median(stem_self_efficacy, na.rm = T)) & (prior_knowledge > median(prior_knowledge, na.rm = T))) %>% 
  filter(flag) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm1b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(flag = (stem_anxiety <= median(stem_anxiety, na.rm = T)) & (stem_self_efficacy > median(stem_self_efficacy, na.rm = T)) & (prior_knowledge > median(prior_knowledge, na.rm = T))) %>% 
  filter(!flag) %>% 
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

knitreg(list(lm1a, lm1b), custom.note = "Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. ***, **, and * indicate significance at 1%, 5%, and 10%.", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F, custom.coef.map = list("fac_active_teaching" = "Active learning"))
  Model 1 Model 2
Active learning -0.004 -0.011
  (0.020) (0.015)
Num. obs. 6137 23890
Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. , , and indicate significance at 1%, 5%, and 10%.

Interaction of this flag [Low anxiety High self-efficacy High prior knowledge] with active learning:

df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(flag = (stem_anxiety <= median(stem_anxiety, na.rm = T)) & (stem_self_efficacy > median(stem_self_efficacy, na.rm = T)) & (prior_knowledge > median(prior_knowledge, na.rm = T))) %>% 
  lm_robust(course_rank ~ fac_active_teaching * flag + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid) %>% 
  knitreg(stars = c(0.01, 0.05, 0.1), include.ci = FALSE, dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F, omit.coef = "(professor)|(highed)|(phd)|(elite)|(female)|(^high)")
  Model 1
fac_active_teaching -0.000
  (0.014)
flagTRUE  
   
fac_active_teaching:flagTRUE -0.035**
  (0.017)
Num. obs. 30027
***p < 0.01; **p < 0.05; *p < 0.1

1.3.5.2 Based on terciles

lm1a <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(flag = (stem_anxiety_tercile == 1 & stem_self_efficacy_tercile == 3 & prior_knowledge_tercile == 3)) %>% 
  filter(flag) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

lm1b <-
  df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(flag = (stem_anxiety_tercile == 1 & stem_self_efficacy_tercile == 3 & prior_knowledge_tercile == 3)) %>% 
  filter(!flag) %>%
  lm_robust(course_rank ~ fac_active_teaching + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid)

knitreg(list(lm1a, lm1b), custom.note = "Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. ***, **, and * indicate significance at 1%, 5%, and 10%.", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F, custom.coef.map = list("fac_active_teaching" = "Active learning"))
  Model 1 Model 2
Active learning 0.052 -0.015
  (0.034) (0.014)
Num. obs. 2642 27401
Notes: Each observation is a student-course. The dependent variable is the student course grade on a standardized scale (mean 0, standard deviation 1). The treatment is active learning on a standardized scale (mean 0, standard deviation 1). Grades are provided at the course level and not at the faculty level. All models include faculty controls, student fixed effects, and course fixed effects. Faculty controls include faculty rank, experience, educational qualifications, and gender. Standard errors are clustered at the faculty level. , , and indicate significance at 1%, 5%, and 10%.

Interaction of this flag [Low anxiety High self-efficacy High prior knowledge] with active learning:

df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  mutate(flag = (stem_anxiety_tercile == 1 & stem_self_efficacy_tercile == 3 & prior_knowledge_tercile == 3)) %>% 
  lm_robust(course_rank ~ fac_active_teaching * flag + fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ stdid + fe_var, se_type = "stata", clusters = facid) %>% 
  knitreg(stars = c(0.01, 0.05, 0.1), include.ci = FALSE, dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F, omit.coef = "(professor)|(highed)|(phd)|(elite)|(female)|(^high)")
  Model 1
fac_active_teaching -0.008
  (0.014)
flagTRUE  
   
fac_active_teaching:flagTRUE -0.001
  (0.020)
Num. obs. 30043
***p < 0.01; **p < 0.05; *p < 0.1



1.4 Table E3

1.4.1 Student characteristics

df %>%
  distinct(stdid, .keep_all = T) %>%
  skim(female, rural, reservation_stu, father_college, mother_college)
Data summary
Name Piped data
Number of rows 2266
Number of columns 32
_______________________
Column type frequency:
numeric 5
________________________
Group variables None

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
female 2 1.00 0.44 0.50 0 0 0 1 1 ▇▁▁▁▆
rural 20 0.99 0.47 0.50 0 0 0 1 1 ▇▁▁▁▇
reservation_stu 4 1.00 0.54 0.50 0 0 1 1 1 ▇▁▁▁▇
father_college 11 1.00 0.50 0.50 0 0 0 1 1 ▇▁▁▁▇
mother_college 10 1.00 0.35 0.48 0 0 0 1 1 ▇▁▁▁▅

Balance:

df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  lm_robust(fac_active_teaching ~ female, data = ., fixed_effects = ~ fe_var, se_type = "stata", clusters = facid) %>%
  summary()
## 
## Call:
## lm_robust(formula = fac_active_teaching ~ female, data = ., clusters = facid, 
##     fixed_effects = ~fe_var, se_type = "stata")
## 
## Standard error type:  stata 
## 
## Coefficients:
##          Estimate Std. Error t value Pr(>|t|) CI Lower CI Upper  DF
## female -0.0001819    0.00583 -0.0312   0.9751 -0.01164  0.01127 470
## 
## Multiple R-squared:  0.694 , Adjusted R-squared:  0.6907
## Multiple R-squared (proj. model):  1.985e-08 ,   Adjusted R-squared (proj. model):  -0.01073 
## F-statistic (proj. model): 0.0009737 on 1 and 470 DF,  p-value: 0.9751
df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  lm_robust(fac_active_teaching ~ rural, data = ., fixed_effects = ~ fe_var, se_type = "stata", clusters = facid) %>%
  summary()
## 
## Call:
## lm_robust(formula = fac_active_teaching ~ rural, data = ., clusters = facid, 
##     fixed_effects = ~fe_var, se_type = "stata")
## 
## Standard error type:  stata 
## 
## Coefficients:
##        Estimate Std. Error t value Pr(>|t|) CI Lower CI Upper  DF
## rural -0.004953   0.005011 -0.9884   0.3235  -0.0148 0.004894 469
## 
## Multiple R-squared:  0.6924 ,    Adjusted R-squared:  0.689
## Multiple R-squared (proj. model):  2.281e-05 ,   Adjusted R-squared (proj. model):  -0.01082 
## F-statistic (proj. model): 0.977 on 1 and 469 DF,  p-value: 0.3235
df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  lm_robust(fac_active_teaching ~ reservation_stu, data = ., fixed_effects = ~ fe_var, se_type = "stata", clusters = facid) %>%
  summary()
## 
## Call:
## lm_robust(formula = fac_active_teaching ~ reservation_stu, data = ., 
##     clusters = facid, fixed_effects = ~fe_var, se_type = "stata")
## 
## Standard error type:  stata 
## 
## Coefficients:
##                  Estimate Std. Error t value Pr(>|t|) CI Lower CI Upper  DF
## reservation_stu -0.004702   0.004694  -1.002    0.317 -0.01392 0.004521 470
## 
## Multiple R-squared:  0.6937 ,    Adjusted R-squared:  0.6904
## Multiple R-squared (proj. model):  1.965e-05 ,   Adjusted R-squared (proj. model):  -0.01072 
## F-statistic (proj. model): 1.004 on 1 and 470 DF,  p-value: 0.317
df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  lm_robust(fac_active_teaching ~ father_college, data = ., fixed_effects = ~ fe_var, se_type = "stata", clusters = facid) %>%
  summary()
## 
## Call:
## lm_robust(formula = fac_active_teaching ~ father_college, data = ., 
##     clusters = facid, fixed_effects = ~fe_var, se_type = "stata")
## 
## Standard error type:  stata 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)  CI Lower CI Upper  DF
## father_college 0.001393   0.005104  0.2729   0.7851 -0.008636  0.01142 470
## 
## Multiple R-squared:  0.6942 ,    Adjusted R-squared:  0.6909
## Multiple R-squared (proj. model):  1.812e-06 ,   Adjusted R-squared (proj. model):  -0.01077 
## F-statistic (proj. model): 0.07447 on 1 and 470 DF,  p-value: 0.7851
df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  lm_robust(fac_active_teaching ~ mother_college, data = ., fixed_effects = ~ fe_var, se_type = "stata", clusters = facid) %>%
  summary()
## 
## Call:
## lm_robust(formula = fac_active_teaching ~ mother_college, data = ., 
##     clusters = facid, fixed_effects = ~fe_var, se_type = "stata")
## 
## Standard error type:  stata 
## 
## Coefficients:
##                 Estimate Std. Error t value Pr(>|t|) CI Lower CI Upper  DF
## mother_college -0.002084   0.005104 -0.4082   0.6833 -0.01211 0.007946 470
## 
## Multiple R-squared:  0.6941 ,    Adjusted R-squared:  0.6908
## Multiple R-squared (proj. model):  3.731e-06 ,   Adjusted R-squared (proj. model):  -0.01076 
## F-statistic (proj. model): 0.1666 on 1 and 470 DF,  p-value: 0.6833

1.4.2 Faculty characteristics

df %>%
  distinct(facid, .keep_all = T) %>%
  skim(fac_associate_professor, fac_professor, fac_yearsinhighed, fac_highest_degree_phd, fac_highest_degree_phd_in_prog, fac_degree_college_elite, fac_female)
Data summary
Name Piped data
Number of rows 471
Number of columns 32
_______________________
Column type frequency:
numeric 7
________________________
Group variables None

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
fac_associate_professor 2 1 0.17 0.38 0 0 0 0 1 ▇▁▁▁▂
fac_professor 2 1 0.08 0.27 0 0 0 0 1 ▇▁▁▁▁
fac_yearsinhighed 2 1 9.94 6.45 0 6 9 13 46 ▇▆▁▁▁
fac_highest_degree_phd 0 1 0.31 0.46 0 0 0 1 1 ▇▁▁▁▃
fac_highest_degree_phd_in_prog 0 1 0.15 0.36 0 0 0 0 1 ▇▁▁▁▂
fac_degree_college_elite 2 1 0.31 0.46 0 0 0 1 1 ▇▁▁▁▃
fac_female 1 1 0.32 0.47 0 0 0 1 1 ▇▁▁▁▃

Balance:

df %>%
  mutate(fe_var = str_c(department_id, course_name, sep = "_")) %>%
  lm_robust(fac_active_teaching ~ fac_associate_professor + fac_professor + fac_yearsinhighed + fac_highest_degree_phd + fac_highest_degree_phd_in_prog + fac_degree_college_elite + fac_female, data = ., fixed_effects = ~ fe_var, se_type = "stata", clusters = facid) %>%
  summary()
## 
## Call:
## lm_robust(formula = fac_active_teaching ~ fac_associate_professor + 
##     fac_professor + fac_yearsinhighed + fac_highest_degree_phd + 
##     fac_highest_degree_phd_in_prog + fac_degree_college_elite + 
##     fac_female, data = ., clusters = facid, fixed_effects = ~fe_var, 
##     se_type = "stata")
## 
## Standard error type:  stata 
## 
## Coefficients:
##                                Estimate Std. Error t value Pr(>|t|)  CI Lower
## fac_associate_professor        -0.03009   0.150677 -0.1997  0.84182 -0.326176
## fac_professor                   0.20549   0.188621  1.0894  0.27653 -0.165163
## fac_yearsinhighed               0.01091   0.009911  1.1009  0.27149 -0.008564
## fac_highest_degree_phd          0.08272   0.179754  0.4602  0.64558 -0.270503
## fac_highest_degree_phd_in_prog  0.37748   0.163013  2.3157  0.02101  0.057154
## fac_degree_college_elite       -0.09287   0.109919 -0.8449  0.39860 -0.308867
## fac_female                     -0.22270   0.118935 -1.8725  0.06177 -0.456416
##                                CI Upper  DF
## fac_associate_professor         0.26600 467
## fac_professor                   0.57614 467
## fac_yearsinhighed               0.03039 467
## fac_highest_degree_phd          0.43595 467
## fac_highest_degree_phd_in_prog  0.69781 467
## fac_degree_college_elite        0.12313 467
## fac_female                      0.01101 467
## 
## Multiple R-squared:   0.71 , Adjusted R-squared:  0.7069
## Multiple R-squared (proj. model):  0.05246 , Adjusted R-squared (proj. model):  0.04206 
## F-statistic (proj. model): 2.172 on 7 and 467 DF,  p-value: 0.03547

2 Cross-country sample

2.1 Table 5: Main effects

df <- read_csv("data_crosscountry_sample_v3.csv")
lm1 <-
  df %>% 
  filter(country == "China") %>%
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

lm2 <-
  df %>%
  filter(country == "India") %>%
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

lm3 <-
  df %>%
  filter(country == "Russia") %>%
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

knitreg(list(lm1, lm2, lm3), custom.note = "%stars", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, custom.model.names = c("China", "India", "Russia"), dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 3, include.rsquared = F, include.adjrs = F, include.rmse = F, include.nclust = F, custom.coef.names = c("Active learning", "Baseline achievement", "Faculty experience", "Faculty undergrad from elite college", "Faculty graduate from elite college", "Faculty total publications", "Faculty female", "Faculty highest degree is PhD", "Professor", "Associate Professor"), custom.coef.map = list("active_score" = "Active learning"))
  China India Russia
Active learning 0.051 0.032 -0.016
  (0.061) (0.020) (0.056)
Num. obs. 1560 6618 1094
***p < 0.01; **p < 0.05; *p < 0.1

Notes:

  1. The dependent variable is the math/physics test z-scores.
  2. All models include cross-subject (math and physics) student fixed effects.
  3. Baseline achievement refers to baseline achievement in math and physics tests administered to students.
  4. Standard errors are clustered at the department level.

2.1.1 Bayes Factor

China:

BF(
  x = coef(lm1),
  Sigma = vcov(lm1),
  n = nobs(lm1),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm1), hypothesis = "active_score = 0", Sigma = vcov(lm1), 
##     n = nobs(lm1))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.933  0.013  0.054
## g1_score                   0.949  0.032  0.019
## bfac_yearsinhighed         0.951  0.027  0.022
## bfac_degree_college_elite  0.952  0.025  0.023
## bfac_degree_univ_elite     0.950  0.020  0.029
## bfac_publications          0.928  0.059  0.013
## bfac_female                0.903  0.086  0.011
## bfac_highest_degree_phd    0.950  0.030  0.020
## bfac_professor             0.949  0.018  0.033
## bfac_associate_professor   0.942  0.015  0.043
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.965
## H2               0.035
## 
## Evidence matrix (BFs):
##       H1     H2
## H1 1.000 27.649
## H2 0.036  1.000
## 
## Specification table:
##    complex= complex>  fit= fit>    BF= BF>           BF   PHP
## H1    0.166        1 4.582    1 27.649   1 1.017646e+12 0.965
## H2    1.000        1 1.000    1  1.000   1 2.718000e+00 0.035
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

India:

BF(
  x = coef(lm2),
  Sigma = vcov(lm2),
  n = nobs(lm2),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm2), hypothesis = "active_score = 0", Sigma = vcov(lm2), 
##     n = nobs(lm2))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.919  0.004  0.077
## g1_score                   0.943  0.052  0.005
## bfac_yearsinhighed         0.975  0.016  0.009
## bfac_degree_college_elite  0.799  0.198  0.003
## bfac_degree_univ_elite     0.965  0.007  0.028
## bfac_publications          0.967  0.026  0.007
## bfac_female                0.971  0.008  0.021
## bfac_highest_degree_phd    0.974  0.009  0.017
## bfac_professor             0.969  0.023  0.007
## bfac_associate_professor   0.976  0.013  0.011
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.958
## H2               0.042
## 
## Evidence matrix (BFs):
##       H1     H2
## H1 1.000 22.596
## H2 0.044  1.000
## 
## Specification table:
##    complex= complex>  fit= fit>    BF= BF>           BF   PHP
## H1    0.243        1 5.497    1 22.596   1 6.503363e+09 0.958
## H2    1.000        1 1.000    1  1.000   1 2.718000e+00 0.042
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

Russia:

BF(
  x = coef(lm3),
  Sigma = vcov(lm3),
  n = nobs(lm3),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm3), hypothesis = "active_score = 0", Sigma = vcov(lm3), 
##     n = nobs(lm3))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.941  0.036  0.023
## g1_score                   0.833  0.010  0.157
## bfac_yearsinhighed         0.939  0.040  0.021
## bfac_degree_college_elite     NA     NA     NA
## bfac_degree_univ_elite        NA     NA     NA
## bfac_publications          0.876  0.112  0.012
## bfac_female                0.838  0.152  0.010
## bfac_highest_degree_phd    0.919  0.016  0.066
## bfac_professor             0.939  0.039  0.022
## bfac_associate_professor   0.909  0.077  0.014
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1                   0
## H2                   1
## 
## Evidence matrix (BFs):
##     H1 H2
## H1   1  0
## H2 Inf  1
## 
## Specification table:
##    complex= complex> fit= fit> BF= BF>    BF PHP
## H1      Inf        1    0    1   0   1 1.000   0
## H2        1        1    1    1   1   1 2.718   1
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

2.2 Table 6: Heterogeneity

2.2.1 By gender

lm1a <-
  df %>%
  filter(country == "India", female == 1) %>%
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

lm1b <-
  df %>%
  filter(country == "India", female == 0) %>% 
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

lm2a <-
  df %>%
  filter(country == "China", female == 1) %>% 
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

lm2b <-
  df %>%
  filter(country == "China", female == 0) %>% 
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

lm3a <-
  df %>%
  filter(country == "Russia", female == 1) %>% 
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

lm3b <-
  df %>%
  filter(country == "Russia", female == 0) %>% 
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

knitreg(list(lm1a, lm1b, lm2a, lm2b, lm3a, lm3b), custom.note = "%stars", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, custom.model.names = c("India Female", "India Male", "China Female", "China Male", "Russia Female", "Russia Male"), dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 2, include.rsquared = F, include.nclust = F, include.adjrs = F, include.rmse = F, custom.coef.names = c("Active learning", "Baseline achievement", "Faculty experience", "Faculty undergrad from elite college", "Faculty graduate from elite college", "Faculty total publications", "Faculty female", "Faculty highest degree is PhD", "Professor", "Associate Professor"), custom.coef.map = list("active_score" = "Active learning"))
  India Female India Male China Female China Male Russia Female Russia Male
Active learning 0.03 0.03 0.03 0.07 -0.06 -0.01
  (0.03) (0.02) (0.14) (0.08) (0.08) (0.06)
Num. obs. 2594 4024 452 1108 238 856
***p < 0.01; **p < 0.05; *p < 0.1

Notes:

  1. The dependent variable is the math/physics test z-scores.
  2. All models include cross-subject (math and physics) student fixed effects.
  3. Baseline achievement refers to baseline achievement in math and physics tests administered to students.
  4. Standard errors are clustered at the department level.

2.2.1.1 Bayes Factor

India female:

BF(
  x = coef(lm1a),
  Sigma = vcov(lm1a),
  n = nobs(lm1a),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm1a), hypothesis = "active_score = 0", Sigma = vcov(lm1a), 
##     n = nobs(lm1a))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.943  0.010  0.047
## g1_score                   0.962  0.021  0.017
## bfac_yearsinhighed         0.960  0.026  0.014
## bfac_degree_college_elite  0.908  0.084  0.008
## bfac_degree_univ_elite     0.962  0.022  0.017
## bfac_publications          0.956  0.031  0.013
## bfac_female                0.960  0.015  0.025
## bfac_highest_degree_phd    0.954  0.012  0.034
## bfac_professor             0.922  0.070  0.008
## bfac_associate_professor   0.958  0.013  0.029
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1                0.97
## H2                0.03
## 
## Evidence matrix (BFs):
##      H1    H2
## H1 1.00 32.89
## H2 0.03  1.00
## 
## Specification table:
##    complex= complex>  fit= fit>   BF= BF>           BF  PHP
## H1    0.237        1 7.809    1 32.89   1 1.923347e+14 0.97
## H2    1.000        1 1.000    1  1.00   1 2.718000e+00 0.03
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

India male:

BF(
  x = coef(lm1b),
  Sigma = vcov(lm1b),
  n = nobs(lm1b),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm1b), hypothesis = "active_score = 0", Sigma = vcov(lm1b), 
##     n = nobs(lm1b))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.926  0.006  0.068
## g1_score                   0.815  0.181  0.004
## bfac_yearsinhighed         0.969  0.018  0.013
## bfac_degree_college_elite  0.716  0.281  0.003
## bfac_degree_univ_elite     0.931  0.007  0.062
## bfac_publications          0.959  0.032  0.009
## bfac_female                0.964  0.010  0.026
## bfac_highest_degree_phd    0.969  0.014  0.017
## bfac_professor             0.968  0.020  0.012
## bfac_associate_professor   0.959  0.032  0.009
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.961
## H2               0.039
## 
## Evidence matrix (BFs):
##      H1     H2
## H1 1.00 24.971
## H2 0.04  1.000
## 
## Specification table:
##    complex= complex>  fit= fit>    BF= BF>           BF   PHP
## H1     0.26        1 6.493    1 24.971   1 6.993193e+10 0.961
## H2     1.00        1 1.000    1  1.000   1 2.718000e+00 0.039
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

China female:

BF(
  x = coef(lm2a),
  Sigma = vcov(lm2a),
  n = nobs(lm2a),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm2a), hypothesis = "active_score = 0", Sigma = vcov(lm2a), 
##     n = nobs(lm2a))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.912  0.036  0.053
## g1_score                   0.543  0.008  0.449
## bfac_yearsinhighed         0.892  0.082  0.026
## bfac_degree_college_elite  0.774  0.015  0.211
## bfac_degree_univ_elite     0.906  0.031  0.063
## bfac_publications          0.832  0.149  0.018
## bfac_female                0.912  0.051  0.037
## bfac_highest_degree_phd    0.913  0.048  0.039
## bfac_professor             0.882  0.024  0.094
## bfac_associate_professor   0.908  0.032  0.059
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.954
## H2               0.046
## 
## Evidence matrix (BFs):
##       H1     H2
## H1 1.000 20.624
## H2 0.048  1.000
## 
## Specification table:
##    complex= complex>  fit= fit>    BF= BF>           BF   PHP
## H1    0.138        1 2.852    1 20.624   1 9.055797e+08 0.954
## H2    1.000        1 1.000    1  1.000   1 2.718000e+00 0.046
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

China male:

BF(
  x = coef(lm2b),
  Sigma = vcov(lm2b),
  n = nobs(lm2b),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm2b), hypothesis = "active_score = 0", Sigma = vcov(lm2b), 
##     n = nobs(lm2b))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.917  0.015  0.068
## g1_score                   0.734  0.258  0.008
## bfac_yearsinhighed         0.943  0.025  0.032
## bfac_degree_college_elite  0.923  0.061  0.016
## bfac_degree_univ_elite     0.941  0.022  0.037
## bfac_publications          0.938  0.042  0.020
## bfac_female                0.878  0.110  0.012
## bfac_highest_degree_phd    0.942  0.034  0.024
## bfac_professor             0.943  0.026  0.031
## bfac_associate_professor   0.936  0.020  0.045
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.957
## H2               0.043
## 
## Evidence matrix (BFs):
##       H1     H2
## H1 1.000 22.055
## H2 0.045  1.000
## 
## Specification table:
##    complex= complex>  fit= fit>    BF= BF>           BF   PHP
## H1    0.159        1 3.517    1 22.055   1 3.789339e+09 0.957
## H2    1.000        1 1.000    1  1.000   1 2.718000e+00 0.043
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

Russia female:

BF(
  x = coef(lm3a),
  Sigma = vcov(lm3a),
  n = nobs(lm3a),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm3a), hypothesis = "active_score = 0", Sigma = vcov(lm3a), 
##     n = nobs(lm3a))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.854  0.112  0.033
## g1_score                   0.885  0.054  0.061
## bfac_yearsinhighed         0.871  0.090  0.039
## bfac_degree_college_elite     NA     NA     NA
## bfac_degree_univ_elite        NA     NA     NA
## bfac_publications          0.881  0.072  0.046
## bfac_female                0.867  0.095  0.038
## bfac_highest_degree_phd    0.885  0.057  0.058
## bfac_professor             0.885  0.062  0.053
## bfac_associate_professor   0.869  0.092  0.038
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1                   0
## H2                   1
## 
## Evidence matrix (BFs):
##     H1 H2
## H1   1  0
## H2 Inf  1
## 
## Specification table:
##    complex= complex> fit= fit> BF= BF>    BF PHP
## H1      Inf        1    0    1   0   1 1.000   0
## H2        1        1    1    1   1   1 2.718   1
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

Russia male:

BF(
  x = coef(lm3b),
  Sigma = vcov(lm3b),
  n = nobs(lm3b),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm3b), hypothesis = "active_score = 0", Sigma = vcov(lm3b), 
##     n = nobs(lm3b))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.936  0.034  0.030
## g1_score                   0.799  0.011  0.190
## bfac_yearsinhighed         0.930  0.046  0.023
## bfac_degree_college_elite     NA     NA     NA
## bfac_degree_univ_elite        NA     NA     NA
## bfac_publications          0.868  0.118  0.014
## bfac_female                0.827  0.161  0.012
## bfac_highest_degree_phd    0.908  0.017  0.075
## bfac_professor             0.933  0.041  0.025
## bfac_associate_professor   0.907  0.076  0.017
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1                   0
## H2                   1
## 
## Evidence matrix (BFs):
##     H1 H2
## H1   1  0
## H2 Inf  1
## 
## Specification table:
##    complex= complex> fit= fit> BF= BF>    BF PHP
## H1      Inf        1    0    1   0   1 1.000   0
## H2        1        1    1    1   1   1 2.718   1
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

2.2.2 By socioeconomic status

lm1a <-
  df %>%
  filter(country == "India", ses_lowest_tercile == 0) %>% 
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

lm1b <-
  df %>%
  filter(country == "India", ses_lowest_tercile == 1) %>% 
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

lm2a <-
  df %>%
  filter(country == "China", ses_lowest_tercile == 0) %>% 
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

lm2b <-
  df %>%
  filter(country == "China", ses_lowest_tercile == 1) %>% 
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

lm3a <-
  df %>%
  filter(country == "Russia", ses_lowest_tercile == 0) %>% 
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

lm3b <-
  df %>%
  filter(country == "Russia", ses_lowest_tercile == 1) %>%
  lm_robust(g3_score ~ active_score + g1_score + bfac_yearsinhighed + bfac_degree_college_elite + bfac_degree_univ_elite + bfac_publications + bfac_female + bfac_highest_degree_phd + bfac_professor + bfac_associate_professor, fixed_effects = ~ stdid, data = ., clusters = department_id, se_type = "stata")

knitreg(list(lm1a, lm1b, lm2a, lm2b, lm3a, lm3b), custom.note = "%stars", stars = c(0.01, 0.05, 0.1), include.ci = FALSE, custom.model.names = c("India High SES", "India Low SES", "China High SES", "China Low SES", "Russia High SES", "Russia Low SES"), dcolumn = TRUE, booktabs = TRUE, float.pos = "H", caption = "", digits = 2, include.rsquared = F, include.adjrs = F, include.nclust = F, include.rmse = F, custom.coef.names = c("Active learning", "Baseline achievement", "Faculty experience", "Faculty undergrad from elite college", "Faculty graduate from elite college", "Faculty total publications", "Faculty female", "Faculty highest degree is PhD", "Professor", "Associate Professor"), custom.coef.map = list("active_score" = "Active learning"))
  India High SES India Low SES China High SES China Low SES Russia High SES Russia Low SES
Active learning 0.04 0.01 -0.01 0.16** -0.00 -0.04
  (0.02) (0.04) (0.09) (0.07) (0.07) (0.09)
Num. obs. 4490 2080 944 616 704 390
***p < 0.01; **p < 0.05; *p < 0.1

Notes:

  1. The dependent variable is the math/physics test z-scores.
  2. All models include cross-subject (math and physics) student fixed effects.
  3. Baseline achievement refers to baseline achievement in math and physics tests administered to students.
  4. Standard errors are clustered at the department level.

2.2.2.1 Bayes Factor

India high SES:

BF(
  x = coef(lm1a),
  Sigma = vcov(lm1a),
  n = nobs(lm1a),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm1a), hypothesis = "active_score = 0", Sigma = vcov(lm1a), 
##     n = nobs(lm1a))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.896  0.005  0.099
## g1_score                   0.927  0.067  0.006
## bfac_yearsinhighed         0.969  0.020  0.011
## bfac_degree_college_elite  0.769  0.227  0.004
## bfac_degree_univ_elite     0.964  0.009  0.027
## bfac_publications          0.963  0.028  0.009
## bfac_female                0.957  0.008  0.035
## bfac_highest_degree_phd    0.968  0.010  0.022
## bfac_professor             0.965  0.026  0.009
## bfac_associate_professor   0.971  0.015  0.014
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.945
## H2               0.055
## 
## Evidence matrix (BFs):
##       H1     H2
## H1 1.000 17.214
## H2 0.058  1.000
## 
## Specification table:
##    complex= complex>  fit= fit>    BF= BF>           BF   PHP
## H1    0.257        1 4.432    1 17.214   1 29915761.375 0.945
## H2    1.000        1 1.000    1  1.000   1        2.718 0.055
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

India low SES:

BF(
  x = coef(lm1b),
  Sigma = vcov(lm1b),
  n = nobs(lm1b),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm1b), hypothesis = "active_score = 0", Sigma = vcov(lm1b), 
##     n = nobs(lm1b))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.956  0.016  0.028
## g1_score                   0.948  0.039  0.013
## bfac_yearsinhighed         0.957  0.026  0.017
## bfac_degree_college_elite  0.942  0.046  0.012
## bfac_degree_univ_elite     0.935  0.011  0.054
## bfac_publications          0.949  0.038  0.013
## bfac_female                0.954  0.031  0.015
## bfac_highest_degree_phd    0.958  0.023  0.020
## bfac_professor             0.957  0.026  0.017
## bfac_associate_professor   0.958  0.020  0.022
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.977
## H2               0.023
## 
## Evidence matrix (BFs):
##       H1     H2
## H1 1.000 43.246
## H2 0.023  1.000
## 
## Specification table:
##    complex= complex>  fit= fit>    BF= BF>          BF   PHP
## H1    0.218        1 9.434    1 43.246   1 6.04472e+18 0.977
## H2    1.000        1 1.000    1  1.000   1 2.71800e+00 0.023
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

China high SES:

BF(
  x = coef(lm2a),
  Sigma = vcov(lm2a),
  n = nobs(lm2a),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm2a), hypothesis = "active_score = 0", Sigma = vcov(lm2a), 
##     n = nobs(lm2a))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.939  0.033  0.029
## g1_score                   0.939  0.031  0.030
## bfac_yearsinhighed         0.929  0.020  0.051
## bfac_degree_college_elite  0.938  0.035  0.027
## bfac_degree_univ_elite     0.936  0.025  0.039
## bfac_publications          0.927  0.053  0.020
## bfac_female                0.913  0.070  0.017
## bfac_highest_degree_phd    0.937  0.025  0.038
## bfac_professor             0.939  0.030  0.031
## bfac_associate_professor   0.936  0.024  0.040
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.968
## H2               0.032
## 
## Evidence matrix (BFs):
##       H1     H2
## H1 1.000 30.627
## H2 0.033  1.000
## 
## Specification table:
##    complex= complex>  fit= fit>    BF= BF>           BF   PHP
## H1    0.148        1 4.519    1 30.627   1 2.000742e+13 0.968
## H2    1.000        1 1.000    1  1.000   1 2.718000e+00 0.032
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

China low SES:

BF(
  x = coef(lm2b),
  Sigma = vcov(lm2b),
  n = nobs(lm2b),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm2b), hypothesis = "active_score = 0", Sigma = vcov(lm2b), 
##     n = nobs(lm2b))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.514  0.006  0.480
## g1_score                   0.901  0.078  0.021
## bfac_yearsinhighed         0.858  0.126  0.016
## bfac_degree_college_elite  0.922  0.029  0.049
## bfac_degree_univ_elite     0.925  0.036  0.039
## bfac_publications          0.894  0.086  0.020
## bfac_female                0.890  0.090  0.020
## bfac_highest_degree_phd    0.886  0.095  0.019
## bfac_professor             0.921  0.028  0.051
## bfac_associate_professor   0.910  0.023  0.067
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1               0.679
## H2               0.321
## 
## Evidence matrix (BFs):
##       H1    H2
## H1 1.000 2.111
## H2 0.474 1.000
## 
## Specification table:
##    complex= complex>  fit= fit>   BF= BF>    BF   PHP
## H1    0.228        1 0.481    1 2.111   1 8.258 0.679
## H2    1.000        1 1.000    1 1.000   1 2.718 0.321
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

Russia high SES:

BF(
  x = coef(lm3a),
  Sigma = vcov(lm3a),
  n = nobs(lm3a),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm3a), hypothesis = "active_score = 0", Sigma = vcov(lm3a), 
##     n = nobs(lm3a))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.930  0.035  0.035
## g1_score                   0.853  0.015  0.132
## bfac_yearsinhighed         0.923  0.051  0.025
## bfac_degree_college_elite     NA     NA     NA
## bfac_degree_univ_elite        NA     NA     NA
## bfac_publications          0.837  0.150  0.014
## bfac_female                0.791  0.197  0.012
## bfac_highest_degree_phd    0.915  0.022  0.063
## bfac_professor             0.923  0.051  0.025
## bfac_associate_professor   0.902  0.078  0.019
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1                   0
## H2                   1
## 
## Evidence matrix (BFs):
##     H1 H2
## H1   1  0
## H2 Inf  1
## 
## Specification table:
##    complex= complex> fit= fit> BF= BF>    BF PHP
## H1      Inf        1    0    1   0   1 1.000   0
## H2        1        1    1    1   1   1 2.718   1
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

Russia low SES:

BF(
  x = coef(lm3b),
  Sigma = vcov(lm3b),
  n = nobs(lm3b),
  hypothesis = "active_score = 0"
) %>% 
  summary()
## Call:
## BF.default(x = coef(lm3b), hypothesis = "active_score = 0", Sigma = vcov(lm3b), 
##     n = nobs(lm3b))
## 
## Bayesian hypothesis test
## Type: exploratory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities
## 
## Model parameters:
##                           Pr(=0) Pr(<0) Pr(>0)
## active_score               0.900  0.066  0.034
## g1_score                   0.669  0.012  0.319
## bfac_yearsinhighed         0.907  0.052  0.041
## bfac_degree_college_elite     NA     NA     NA
## bfac_degree_univ_elite        NA     NA     NA
## bfac_publications          0.870  0.105  0.025
## bfac_female                0.846  0.133  0.021
## bfac_highest_degree_phd    0.875  0.025  0.100
## bfac_professor             0.908  0.044  0.048
## bfac_associate_professor   0.875  0.100  0.025
## 
## Bayesian hypothesis test
## Type: confirmatory
## Object: numeric
## Parameter: general parameters
## Method: adjusted fractional Bayes factors using Gaussian approximations
## 
## Posterior probabilities:
##    Pr(hypothesis|data)
## H1                   0
## H2                   1
## 
## Evidence matrix (BFs):
##     H1 H2
## H1   1  0
## H2 Inf  1
## 
## Specification table:
##    complex= complex> fit= fit> BF= BF>    BF PHP
## H1      Inf        1    0    1   0   1 1.000   0
## H2        1        1    1    1   1   1 2.718   1
## 
## Hypotheses:
## H1: active_score=0
## H2: complement

2.3 Table E4: Summary statistics

df %>% 
  distinct(stdid, .keep_all = T) %>%
  compareGroups(country ~ female + age_years + father_college + mother_college, data = ., include.label = F) %>%   
  createTable(show.all = F, show.n = F, show.p.overall = F)

——–Summary descriptives table by ‘country’———


              China       India      Russia    
              N=780      N=3309       N=547    

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ female 0.29 (0.45) 0.39 (0.49) 0.22 (0.41) age_years 21.3 (1.10) 20.2 (0.91) 20.5 (1.30) father_college 0.20 (0.40) 0.59 (0.49) 0.82 (0.38) mother_college 0.15 (0.35) 0.45 (0.50) 0.89 (0.32) ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

df %>% 
  distinct(stdid, .keep_all = T) %>% 
  filter(country == "India") %>% 
  inner_join(read_csv(here::here("data/depweights.csv")), by = "department_id") %>% 
  summarise(x = weighted.mean(father_college, w = sw_f, na.rm = T))

3 A tibble: 1 × 1

  x

1 0.533