Gender Pay Gap Analysis

Reading salary data

bank_salaries <-read.csv("bank_salaries.csv")

#Glimpse of the data:
skim(bank_salaries)
(#tab:read data)Data summary
Name bank_salaries
Number of rows 208
Number of columns 8
_______________________
Column type frequency:
character 2
numeric 6
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
gender 0 1 4 6 0 2 0
PC_job 0 1 2 3 0 2 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
salary 0 1 39921.92 11256.15 26700 33000 37000.0 44000.00 97000 ▇▃▁▁▁
education 0 1 3.16 1.47 1 2 3.0 5.00 5 ▅▅▇▁▇
job_grade 0 1 2.75 1.56 1 1 3.0 4.00 6 ▇▃▂▂▁
years_bank 0 1 9.67 6.99 2 5 8.0 13.00 39 ▇▃▁▁▁
years_prior 0 1 2.38 3.14 0 0 1.0 4.00 18 ▇▂▁▁▁
age 0 1 40.39 10.32 22 32 38.5 47.25 65 ▅▇▆▃▂

Effect of gender on salary

#Looking at mean salaries by gender with confidence intervals
gender_mean_salaries <- bank_salaries %>% 
  group_by(gender) %>% 
  summarise(
            mean = mean(salary),
            SD = sd(salary),
            count = n(),
            t_critical = qt(0.975, count - 1),
            SE = SD / sqrt(count),
            margin_of_error = t_critical * SE,
            CI_low  = mean - margin_of_error,
            CI_high  = mean + margin_of_error
            )

gender_mean_salaries
gendermeanSDcountt_criticalSEmargin_of_errorCI_lowCI_high
Female3.72e+046.71e+031401.98567       1.12e+033.61e+043.83e+04
Male4.55e+041.58e+04682   1.92e+033.83e+034.17e+044.93e+04

Since the two intervals do not overlap, it is clear that there is a significant difference in female and male salaries. We now look at contributing factors.

Visualizing Salary progression by Gender

bank_salaries %>% 
  ggplot() +
  geom_point(aes(x = years_bank, y = salary, color=gender, shape=factor(job_grade))) +
  geom_smooth(aes(x = years_bank, y = salary, color=gender), method = "lm") +
  labs(title = "Difference in Salary progression with experience based on Gender",
       x= "Experience in Bank (yrs)",
       y = "Salary")
## `geom_smooth()` using formula 'y ~ x'

It can be seen that most women are in lower job grades, while there are more men at grades 5 and 6. It can also be noted that there are men with just 12/ 13 years of experience at grade 6 with salaries around 60000 while women in grade 6 with 36 years of experience might still receive a salary of around 20000.

Regression Models to analyse impact of predictors on slalary

mosaic::favstats (salary ~ gender, data=bank_salaries)
genderminQ1medianQ3maxmeansdnmissing
Female2.68e+043.26e+043.54e+044.16e+046.18e+043.72e+046.71e+031400
Male2.67e+043.44e+044.25e+044.86e+049.7e+04 4.55e+041.58e+04680
model1 <- lm(salary ~ gender , data=bank_salaries)
msummary(model1)
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  37209.9      894.5  41.597  < 2e-16 ***
## genderMale    8295.5     1564.5   5.302 2.94e-07 ***
## 
## Residual standard error: 10580 on 206 degrees of freedom
## Multiple R-squared:  0.1201, Adjusted R-squared:  0.1158 
## F-statistic: 28.12 on 1 and 206 DF,  p-value: 2.935e-07
bank_salaries <- bank_salaries %>% 
  mutate( education = as.factor(education),
          job_grade = as.factor(job_grade))

model2 <- lm(salary ~ ., data=bank_salaries)
msummary(model2)
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 26930.292   2455.799  10.966  < 2e-16 ***
## education2   -459.564   1402.853  -0.328 0.743575    
## education3    519.412   1363.220   0.381 0.703609    
## education4    199.212   2415.820   0.082 0.934365    
## education5   2724.608   1626.395   1.675 0.095506 .  
## job_grade2   1558.467   1189.458   1.310 0.191674    
## job_grade3   5236.422   1266.746   4.134 5.32e-05 ***
## job_grade4   8575.398   1501.370   5.712 4.18e-08 ***
## job_grade5  13953.528   1872.157   7.453 2.99e-12 ***
## job_grade6  23967.176   2888.131   8.299 1.80e-14 ***
## years_bank    508.436     99.474   5.111 7.67e-07 ***
## years_prior   152.073    140.535   1.082 0.280559    
## age            -2.128     57.722  -0.037 0.970634    
## genderMale   2650.777   1011.442   2.621 0.009471 ** 
## PC_jobYes    4970.859   1477.816   3.364 0.000928 ***
## 
## Residual standard error: 5666 on 193 degrees of freedom
## Multiple R-squared:  0.7638, Adjusted R-squared:  0.7466 
## F-statistic: 44.57 on 14 and 193 DF,  p-value: < 2.2e-16
model3 <- lm(salary ~ years_bank + gender + education + job_grade, 
             data=bank_salaries)
msummary(model3)
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 27966.93    1463.97  19.103  < 2e-16 ***
## years_bank    472.44      87.16   5.421 1.73e-07 ***
## genderMale   1810.89    1008.66   1.795   0.0741 .  
## education2   -742.01    1407.50  -0.527   0.5987    
## education3    704.42    1342.42   0.525   0.6004    
## education4    171.97    2467.33   0.070   0.9445    
## education5   2646.67    1627.40   1.626   0.1055    
## job_grade2   2222.38    1208.22   1.839   0.0674 .  
## job_grade3   5578.01    1283.44   4.346 2.22e-05 ***
## job_grade4   9068.03    1531.10   5.923 1.40e-08 ***
## job_grade5  14157.59    1896.60   7.465 2.67e-12 ***
## job_grade6  24608.51    2947.57   8.349 1.23e-14 ***
## 
## Residual standard error: 5827 on 196 degrees of freedom
## Multiple R-squared:  0.7463, Adjusted R-squared:  0.7321 
## F-statistic: 52.41 on 11 and 196 DF,  p-value: < 2.2e-16
model4 <- lm(salary ~ years_bank + gender + job_grade, 
             data=bank_salaries)
msummary(model4)
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 28601.48    1054.03  27.135  < 2e-16 ***
## years_bank    404.62      78.75   5.138 6.58e-07 ***
## genderMale   2011.75    1005.38   2.001   0.0467 *  
## job_grade2   2656.22    1183.67   2.244   0.0259 *  
## job_grade3   6423.47    1169.34   5.493 1.19e-07 ***
## job_grade4  10511.86    1372.14   7.661 7.78e-13 ***
## job_grade5  16435.21    1546.66  10.626  < 2e-16 ***
## job_grade6  27699.13    2504.49  11.060  < 2e-16 ***
## 
## Residual standard error: 5849 on 200 degrees of freedom
## Multiple R-squared:  0.7391, Adjusted R-squared:   0.73 
## F-statistic: 80.94 on 7 and 200 DF,  p-value: < 2.2e-16

Accounting for interactive variables:

model5 <- lm(salary ~ years_bank*gender, data=bank_salaries)
mosaic::msummary(model5)
##                       Estimate Std. Error t value Pr(>|t|)    
## (Intercept)            34528.3     1138.0  30.342  < 2e-16 ***
## years_bank               280.0      102.5   2.733  0.00684 ** 
## genderMale             -4098.3     1665.8  -2.460  0.01472 *  
## years_bank:genderMale   1247.8      136.7   9.130  < 2e-16 ***
## 
## Residual standard error: 6816 on 204 degrees of freedom
## Multiple R-squared:  0.6386, Adjusted R-squared:  0.6333 
## F-statistic: 120.2 on 3 and 204 DF,  p-value: < 2.2e-16
model6 <- lm(salary ~ years_bank*gender + job_grade, data=bank_salaries)
mosaic::msummary(model6)
##                       Estimate Std. Error t value Pr(>|t|)    
## (Intercept)           32145.02     989.06  32.501  < 2e-16 ***
## years_bank               52.00      78.64   0.661   0.5092    
## genderMale            -6106.05    1271.27  -4.803 3.07e-06 ***
## job_grade2             2597.76    1011.26   2.569   0.0109 *  
## job_grade3             6221.48     999.26   6.226 2.78e-09 ***
## job_grade4            11050.68    1173.90   9.414  < 2e-16 ***
## job_grade5            15061.14    1330.84  11.317  < 2e-16 ***
## job_grade6            16639.36    2491.68   6.678 2.36e-10 ***
## years_bank:genderMale  1035.00     119.49   8.662 1.60e-15 ***
## 
## Residual standard error: 4997 on 199 degrees of freedom
## Multiple R-squared:  0.8105, Adjusted R-squared:  0.8029 
## F-statistic: 106.4 on 8 and 199 DF,  p-value: < 2.2e-16

While men start with about 6000 lower than women at grade 1, it is possible that they progress faster to higher grades. Men also receive 1035 more than women for every year they are at the bank.

huxreg(model1, model2, model3, model4, model5, model6,
       statistics = c('#observations' = 'nobs', 'R squared' = 'r.squared',
                      'Adj. R Squared' = 'adj.r.squared', 'Residual SE' = 'sigma'),
                      bold_signif = 0.05, stars = NULL ) %>% 
                      set_caption('Comparison of models')
Comparison of models
(1)(2)(3)(4)(5)(6)
(Intercept)37209.929 26930.292 27966.931 28601.475 34528.280 32145.021 
(894.533)(2455.799)(1463.973)(1054.030)(1137.970)(989.060)
genderMale8295.513 2650.777 1810.886 2011.754 -4098.252 -6106.052 
(1564.493)(1011.442)(1008.662)(1005.378)(1665.842)(1271.268)
education2     -459.564 -742.009                
     (1402.853)(1407.502)               
education3     519.412 704.425                
     (1363.220)(1342.418)               
education4     199.212 171.966                
     (2415.820)(2467.329)               
education5     2724.608 2646.671                
     (1626.395)(1627.397)               
job_grade2     1558.467 2222.379 2656.218      2597.756 
     (1189.458)(1208.224)(1183.668)     (1011.256)
job_grade3     5236.422 5578.006 6423.473      6221.480 
     (1266.746)(1283.444)(1169.336)     (999.262)
job_grade4     8575.398 9068.034 10511.865      11050.678 
     (1501.370)(1531.098)(1372.136)     (1173.896)
job_grade5     13953.528 14157.594 16435.206      15061.142 
     (1872.157)(1896.602)(1546.665)     (1330.839)
job_grade6     23967.176 24608.511 27699.131      16639.360 
     (2888.131)(2947.572)(2504.486)     (2491.680)
years_bank     508.436 472.444 404.616 279.963 51.997 
     (99.474)(87.158)(78.753)(102.456)(78.639)
years_prior     152.073                     
     (140.535)                    
age     -2.128                     
     (57.722)                    
PC_jobYes     4970.859                     
     (1477.816)                    
years_bank:genderMale                    1247.798 1034.999 
                    (136.676)(119.493)
#observations208     208     208     208     208     208     
R squared0.120 0.764 0.746 0.739 0.639 0.811 
Adj. R Squared0.116 0.747 0.732 0.730 0.633 0.803 
Residual SE10584.260 5665.699 5826.543 5849.143 6816.298 4997.053 

Distribution of gender at each job grade level

bank_salaries %>% 
  group_by(gender, job_grade) %>% 
  count() %>% 
  pivot_wider(names_from = gender, values_from = n) %>% 
  mutate(percent_female = round(100 * Female / (Female+Male), 2),
         percent_male = round(100 * Male / (Female+Male), 2)) 
## # A tibble: 6 × 5
## # Groups:   job_grade [6]
##   job_grade Female  Male percent_female percent_male
##   <fct>      <int> <int>          <dbl>        <dbl>
## 1 1             48    12          80            20  
## 2 2             29    13          69.0          31.0
## 3 3             36     7          83.7          16.3
## 4 4             17    11          60.7          39.3
## 5 5              9    13          40.9          59.1
## 6 6              1    12           7.69         92.3
bank_salaries %>% 
  group_by(gender, job_grade) %>% 
  count() %>% 
  ggplot(aes(x = job_grade, y=n, fill=gender))+
  geom_col(position = "dodge")

Most women are concentrated at lower job grades while the percentage of men clearly exceeds women at higher levels. Possible reasons include women being overlooked for leadership roles and bias against women of certain age groups especially mid-career.