# environment setup to run ordered logit properly
options(contrasts = rep("contr.treatment", 2))

This chunk loads all the packages to use

#packages for ordered logit
library(tidyverse) # package for data cleaning and plotting
library(readxl) # package for reading excel file
library(broom) # extracting model summary as data frame
library(modelsummary) # deriving model tables
library(scales) # label percent
library(lubridate) # working with dates
library(marginaleffects) #to calculate marginal effects
library(ordinal) # package for ordinal logit regression

Data Preparation

First, import the sampled and coded data set

#import the raw data file
cqc_skills <- read_csv("data/cleaned_sfc_ipw.csv") %>% 
  mutate(form = fct_relevel(form, "FPO"),
         rating = factor(rating),
         Year = factor(year),
         during_covid = after_covid,
         staff_level = staff_level/100)

Detailes about new variables

Employee turnover rate is the percent of employees who leave a company within a specific time period. Turnover rate is commonly calculated by month, quarter, or year and includes both voluntary and involuntary losses.

\[ \text{Employee turnover rate} = \frac{\text{Number of employees who left}}{\text{Average number of employees}} \times 100 \]

\[ \text{Average number of employees} = \frac{\text{(Headcount at the begining of the timeframe + headcount at the end of the timeframe)}}{2} \]

Modeling on rating with staff control

model_order <- clm(rating ~ form + category + region + during_covid,
                data = filter(cqc_skills, domain == "Overall"),
                link = "logit")

model_order_weighted <- clm(rating ~ form + category + region + during_covid,
                data = filter(cqc_skills, domain == "Overall"),
                link = "logit",
                weights = ipw)

model_staff <- lm(staff_level ~ form + category + region + during_covid,
                data = filter(cqc_skills, domain == "Overall"))

model_staff_weighted <- lm(staff_level ~ form + category + region + during_covid,
                data = filter(cqc_skills, domain == "Overall"),
                weights = ipw)

staff_direct_order <- clm(rating ~ form + staff_level + category + region + during_covid,
                data = filter(cqc_skills, domain == "Overall"),
                link = "logit")
staff_direct_order_weighted <- clm(rating ~ form + staff_level + category + region + during_covid,
                data = filter(cqc_skills, domain == "Overall"),
                link = "logit",
                weights = ipw)
staff_models <- modelsummary(list("full" = model_order, "full weighted" = model_order_weighted, 
                                    "staffing" = model_staff, "staffing weighted"= model_staff_weighted, 
                                    "direct" = staff_direct_order, "direct weighted" = staff_direct_order_weighted),
                               coef_omit = "region", exponentiate = F,
                               statistic = "({p.value}) {stars}")
staff_models
full full weighted staffing staffing weighted direct direct weighted
Good|Inadequate 1.990 2.036 1.833 1.861
(<0.001) *** (<0.001) *** (<0.001) *** (<0.001) ***
Inadequate|Outstanding 2.052 2.121 1.894 1.945
(<0.001) *** (<0.001) *** (<0.001) *** (<0.001) ***
Outstanding|Req improv 2.533 2.501 2.399 2.348
(<0.001) *** (<0.001) *** (<0.001) *** (<0.001) ***
formCIC 0.262 0.247 0.604 0.560 0.473 0.484
(0.458) (0.373) (0.044) * (0.065) + (0.188) (0.086) +
formGOV −0.195 −0.254 0.784 0.786 −0.106 −0.148
(0.214) (0.088) + (<0.001) *** (<0.001) *** (0.517) (0.338)
formIND 0.064 0.153 −0.193 −0.176 −0.001 0.079
(0.693) (0.100) (0.135) (0.077) + (0.994) (0.438)
formNPO −0.319 −0.352 0.557 0.569 −0.230 −0.252
(<0.001) *** (<0.001) *** (<0.001) *** (<0.001) *** (0.016) * (<0.001) ***
categoryresidential 0.321 0.342 0.478 0.465 0.329 0.375
(<0.001) *** (<0.001) *** (<0.001) *** (<0.001) *** (<0.001) *** (<0.001) ***
during_covidTRUE 1.341 1.466 −0.150 −0.141 1.340 1.458
(<0.001) *** (<0.001) *** (0.009) ** (0.008) ** (<0.001) *** (<0.001) ***
(Intercept) 1.253 1.277
(<0.001) *** (<0.001) ***
staff_level −0.103 −0.118
(<0.001) *** (<0.001) ***
Num.Obs. 6504 12933 6419 6162 5767 11430
R2 0.034 0.035
R2 Adj. 0.031 0.033
AIC 7749.3 15948.6 27220.8 25224.4 6834.1 13970.4
BIC 7864.5 16075.5 27329.1 25332.0 6954.0 14102.6
Log.Lik. −13594.419 −12596.202
RMSE 1.52 1.52 2.01 1.91 1.51 1.51

Modeling on rating with turnover

model_turnover <- lm(turnover ~ form + category + region + during_covid,
                data = filter(cqc_skills, domain == "Overall"))

model_turnover_weighted <- lm(turnover ~ form + category + region + during_covid,
                data = filter(cqc_skills, domain == "Overall"),
                weights = ipw)

turnover_direct_order <- clm(rating ~ form + turnover + category + region + during_covid,
                data = filter(cqc_skills, domain == "Overall"),
                link = "logit")
turnover_direct_order_weighted <- clm(rating ~ form + turnover + category + region + during_covid,
                data = filter(cqc_skills, domain == "Overall"),
                link = "logit",
                weights = ipw)
staff_models <- modelsummary(list("full" = model_order, "full weighted" = model_order_weighted, 
                                    "turnover" = model_turnover, "turnover weighted"= model_turnover_weighted, 
                                    "direct" = turnover_direct_order, "direct weighted" = turnover_direct_order_weighted),
                               coef_omit = "region", exponentiate = F,
                               statistic = "({p.value}) {stars}")
staff_models
full full weighted turnover turnover weighted direct direct weighted
Good|Inadequate 1.990 2.036 1.969 2.026
(<0.001) *** (<0.001) *** (<0.001) *** (<0.001) ***
Inadequate|Outstanding 2.052 2.121 2.023 2.101
(<0.001) *** (<0.001) *** (<0.001) *** (<0.001) ***
Outstanding|Req improv 2.533 2.501 2.524 2.499
(<0.001) *** (<0.001) *** (<0.001) *** (<0.001) ***
formCIC 0.262 0.247 −5.557 −6.574 0.621 0.649
(0.458) (0.373) (0.463) (0.445) (0.168) (0.064) +
formGOV −0.195 −0.254 −20.189 −20.441 −0.125 −0.179
(0.214) (0.088) + (<0.001) *** (<0.001) *** (0.437) (0.235)
formIND 0.064 0.153 −11.745 −12.417 0.157 0.238
(0.693) (0.100) (<0.001) *** (<0.001) *** (0.388) (0.023) *
formNPO −0.319 −0.352 −7.433 −7.497 −0.221 −0.257
(<0.001) *** (<0.001) *** (<0.001) *** (<0.001) *** (0.035) * (0.002) **
categoryresidential 0.321 0.342 −5.292 −6.214 0.258 0.297
(<0.001) *** (<0.001) *** (<0.001) *** (<0.001) *** (0.002) ** (<0.001) ***
during_covidTRUE 1.341 1.466 2.782 2.711 1.304 1.431
(<0.001) *** (<0.001) *** (0.021) * (0.030) * (<0.001) *** (<0.001) ***
(Intercept) 35.729 35.966
(<0.001) *** (<0.001) ***
turnover 0.002 0.002
(0.008) ** (<0.001) ***
Num.Obs. 6504 12933 5479 5265 4939 9774
R2 0.030 0.026
R2 Adj. 0.028 0.023
AIC 7749.3 15948.6 55736.7 54039.3 5772.3 11783.5
BIC 7864.5 16075.5 55842.4 54144.4 5889.4 11912.8
Log.Lik. −27852.330 −27003.629
RMSE 1.52 1.52 39.04 39.28 1.50 1.49