Read Me

This is the data analysis RMarkdown file for the QCQ data after ISIRC 2022.

Mainly changes: incorporating the contol of before and after COVID

Please read the subtitles and notes added as normal text in this document. Blocks with darker backgrounds are code chunks, mostly with their outputs. I tried to add #comments within the chunck just before the code line to explain the purpose of the code line. Meanwhile I explain the purpose of the section in the texts, so that is where to find information to give you fuller pictures.

# 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(ordinal) # package for ordinal logit regression
library(brant) # brant test for the parallel assumption for ordered logit
library(MASS) # models that work with the brant test

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

Data Preparation

First, import the sampled and coded data set

#import the raw data file
socialcare_raw <- read_csv("data/sample_new_cleaned.csv")

Assign orders to the ordinal level variables and name the organizational form in a reader-friendly way.

#select relevant columns, rename and relabel 
socialcare <- socialcare_raw %>% 
  # recode legal form types to be more readable / easier to present
  mutate(location_id = factor(location_id),
         form = case_when(form_num == 1 ~ "FPO",
                          form_num == 2 ~ "NPO",
                          form_num == 3 ~ "GOV",
                          form_num == 4 ~ "CIC",
                          form_num == 5 ~ "IND",
                          TRUE ~ NA_character_),
         inherited = ifelse(inherited == "Y", TRUE, FALSE),
         rating = recode(rating, 
                         "Insufficient evidence to rate" = "NA",
                         "Requires improvement" = "Req improv"),
         publication_date = dmy(publication_date)) %>% 
  # set the order of the values in the factors 
  mutate(form = ordered(form, levels = c("FPO", "NPO", "GOV", "CIC", "IND")),
         
         # assume the order of the ratings as follows but need to double check with the source 
         rating = ordered(rating, levels = c("Inadequate","Req improv", "Good", "Outstanding"))) %>% 
  
  # creating a new dummy variable for facility category
  mutate(category = case_when(primary_cat == "Community based adult social care services" ~ "community",
                              primary_cat == "Residential social care" ~ "residential",
                              TRUE ~ as.character(NA)),
         # deriving year column and dummy variable for before_covid
         year = year(publication_date),
         after_covid = ifelse(year > 2019, TRUE, FALSE)) %>%

  # converting the ordinal variable to numerical 
  mutate(rating_num = case_when(rating == "Inadequate" ~ 1,
                                rating == "Req improv" ~ 2,
                                rating == "Good" ~ 3,
                                rating == "Outstanding" ~ 4)) %>% 
  # derive the rating dummy
  mutate(rating_higher = ifelse(rating_num > 2, 1, 0))

# show first several rows of the data set derived 
head(socialcare)
## # A tibble: 6 × 39
##    ...1 locati…¹ Locat…² Locat…³ Care …⁴ prima…⁵ Locat…⁶ Locat…⁷ Locat…⁸ Locat…⁹
##   <dbl> <fct>    <chr>   <chr>   <chr>   <chr>   <chr>   <chr>   <chr>   <chr>  
## 1     1 1-10000… VNH4P   69 Ten… N       Commun… 69 Ten… Warmsw… Doncas… DN4 9PE
## 2     2 1-10000… VNH4P   69 Ten… N       Commun… 69 Ten… Warmsw… Doncas… DN4 9PE
## 3     3 1-10000… VNH4P   69 Ten… N       Commun… 69 Ten… Warmsw… Doncas… DN4 9PE
## 4     4 1-10000… VNH4P   69 Ten… N       Commun… 69 Ten… Warmsw… Doncas… DN4 9PE
## 5     5 1-10000… VNH4P   69 Ten… N       Commun… 69 Ten… Warmsw… Doncas… DN4 9PE
## 6     6 1-10000… VNH4P   69 Ten… N       Commun… 69 Ten… Warmsw… Doncas… DN4 9PE
## # … with 29 more variables: `Location Local Authority` <chr>, region <chr>,
## #   `Location NHS Region` <chr>, `Location ONSPD CCG Code` <chr>,
## #   `Location ONSPD CCG` <chr>, `Location Commissioning CCG Code` <lgl>,
## #   `Location Commissioning CCG Name` <lgl>,
## #   `Service / Population Group` <chr>, domain <chr>, rating <ord>,
## #   publication_date <date>, `Report Type` <chr>, inherited <lgl>, URL <chr>,
## #   `Provider ID` <chr>, location_type <chr>, form_num <dbl>, …
socialcare %>% 
  group_by(year, form) %>% 
  drop_na(rating_num) %>% 
  summarise(count = n(),
            perform = mean(rating_num))
## `summarise()` has grouped output by 'year'. You can override using the
## `.groups` argument.
## # A tibble: 34 × 4
## # Groups:   year [6]
##     year form  count perform
##    <dbl> <ord> <int>   <dbl>
##  1  2016 FPO     168    2.96
##  2  2016 NPO      36    2.89
##  3  2016 GOV      12    3   
##  4  2016 CIC       6    2.83
##  5  2016 IND      30    3   
##  6  2017 FPO    4251    3.02
##  7  2017 NPO    1171    3.04
##  8  2017 GOV     210    3.05
##  9  2017 CIC      30    3.07
## 10  2017 IND     376    3.00
## # … with 24 more rows

Descriptive analysis

table1 <- datasummary((category + inherited + after_covid +  region) ~ form,
                      data = socialcare, fmt = 0)
## Warning in !is.null(rmarkdown::metadata$output) && rmarkdown::metadata$output
## %in% : 'length(x) = 3 > 1' in coercion to 'logical(1)'
table1
FPO NPO GOV CIC IND
category community 22454 3365 1194 390 798
residential 41721 9022 1231 114 4355
inherited FALSE 60318 11772 2185 492 5069
TRUE 3869 627 246 12 84
after_covid FALSE 45211 9811 1921 389 3956
TRUE 18976 2588 510 115 1197
region East Midlands 6510 896 306 24 396
East of England 7451 1128 181 108 509
London 7055 1180 246 60 600
North East 2646 654 186 18 144
North West 7911 1448 348 132 774
South East 11835 2400 408 36 930
South West 7304 2070 180 36 858
West Midlands 7547 1303 258 42 498
Yorkshire and The Humber 5928 1320 318 48 444

Running OLS models

The OLS models and the ordered logit models can be written as follows

\(rating_{numerical} = \beta_0 + \beta_1form + \beta_2category+ \beta_3region + \beta_4inherited + u\)

\(log-odds(rating_{ordinal} \leq j) = \beta_{j0} + \beta_1form + \beta_2category+ \beta_3region + \beta_4inherited + u\)

In this section, we first run the OLS models. In the OLS models, we kind of “cheat” R by treating the four rating levels with orders as if they are numbers 1-4. There are the flowing reasons that we report the results from OLS models, even though the more suitable methods should be ordered logit models, about which we will discuss in a while.

  1. The purpose of fitting OLS models is to use them as benchmarks.
  2. Since there are issues like heteroscedasticity, the standard errors calculated are not reliable. But the correlation relationships between the independent variables and dependent variables are still true. So the results are still informative
  3. Plus, compared with the ordered logit models we run later, the results are more straightforward, and more easily give us intuition about how different legal forms of social care providers impact the service quality ratings.
  4. The OLS models are intended to be compared with the ordered logit models. As shown later, the results are generally consistent between the two model families, confirming that our model specification is robust between different models.

OLS with the sub-domain ratings one by one

# run the model loops with nest() method
models_ols <- socialcare %>% 
  group_by(domain) %>% 
  nest()%>% 
  mutate(ols_models = map(data, 
                          ~lm(rating_num ~ form + 
                              category + region + inherited , 
                              data = .x))) %>% 
  mutate(results = map(ols_models, ~tidy(.x, conf.int = TRUE))) %>% 
  pull(ols_models, name = domain)
# run the model loops with nest() method
# add before_covid as control
# add also interaction term
table_ols <- modelsummary(models_ols, statistic = "({p.value}) {stars}")
table_ols
Safe Effective Caring Responsive Well-led Overall
(Intercept) 2.789*** 2.892*** 3.016*** 2.961*** 2.814*** 2.873***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
formNPO 0.082*** 0.040*** 0.027*** 0.064*** 0.100*** 0.082***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
formGOV 0.097*** 0.039* 0.029+ 0.053** 0.097*** 0.081***
(0.000) *** (0.023) * (0.061) + (0.006) ** (0.000) *** (0.001) ***
formCIC 0.100* 0.019 0.079* 0.039 0.109+ 0.104*
(0.030) * (0.604) (0.014) * (0.339) (0.055) + (0.043) *
formIND −0.019 −0.033** −0.004 −0.007 −0.040* −0.036*
(0.214) (0.007) ** (0.712) (0.621) (0.033) * (0.035) *
categoryresidential −0.064*** −0.037*** −0.047*** −0.030*** −0.067*** −0.070***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionEast of England 0.047** 0.041** 0.015 0.035* 0.030 0.043*
(0.004) ** (0.002) ** (0.189) (0.016) * (0.132) (0.017) *
regionLondon 0.048** 0.054*** 0.003 −0.003 0.025 0.019
(0.004) ** (0.000) *** (0.807) (0.820) (0.206) (0.308)
regionNorth East 0.123*** 0.095*** 0.069*** 0.082*** 0.155*** 0.133***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionNorth West 0.067*** 0.064*** 0.022* 0.040** 0.052** 0.052**
(0.000) *** (0.000) *** (0.050) * (0.004) ** (0.007) ** (0.003) **
regionSouth East 0.098*** 0.049*** 0.040*** 0.051*** 0.057** 0.062***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.002) ** (0.000) ***
regionSouth West 0.124*** 0.094*** 0.085*** 0.091*** 0.144*** 0.142***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionWest Midlands 0.019 0.020 −0.015 0.000 −0.075*** −0.030+
(0.233) (0.114) (0.173) (0.982) (0.000) *** (0.092) +
regionYorkshire and The Humber −0.012 0.031* 0.036** 0.008 −0.033 −0.025
(0.467) (0.020) * (0.002) ** (0.576) (0.115) (0.186)
inheritedTRUE −0.018 −0.032** −0.032** −0.032* −0.018 −0.020
(0.248) (0.008) ** (0.003) ** (0.020) * (0.346) (0.260)
Num.Obs. 12966 12931 12927 12953 12964 12942
R2 0.023 0.013 0.017 0.013 0.025 0.023
R2 Adj. 0.021 0.012 0.016 0.012 0.024 0.022
AIC 14402.5 8181.6 5099.3 11037.1 19530.8 16998.2
BIC 14522.0 8301.1 5218.8 11156.6 19650.3 17117.7
Log.Lik. −7185.242 −4074.798 −2533.650 −5502.563 −9749.405 −8483.091
RMSE 0.42 0.33 0.29 0.37 0.51 0.47
# run the model loops with nest() method
# add after_covid as control
models_ols_covid <- socialcare %>% 
  group_by(domain) %>% 
  nest()%>% 
  mutate(ols_models = map(data, 
                          ~lm(rating_num ~ form + after_covid + 
                              category + region + inherited, 
                              data = .x))) %>% 
  mutate(results = map(ols_models, ~tidy(.x, conf.int = TRUE))) %>% 
  pull(ols_models, name = domain) 
table_ols_covid <- modelsummary(models_ols_covid, statistic = "({p.value}) {stars}")
table_ols_covid
Safe Effective Caring Responsive Well-led Overall
(Intercept) 2.879*** 2.925*** 3.036*** 2.986*** 2.923*** 2.982***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
formNPO 0.056*** 0.032*** 0.023** 0.058*** 0.069*** 0.050***
(0.000) *** (0.000) *** (0.002) ** (0.000) *** (0.000) *** (0.000) ***
formGOV 0.069** 0.032+ 0.025 0.048* 0.065* 0.050*
(0.001) ** (0.058) + (0.102) (0.013) * (0.011) * (0.028) *
formCIC 0.084+ 0.016 0.079* 0.037 0.085 0.080+
(0.058) + (0.661) (0.014) * (0.357) (0.118) (0.100) +
formIND −0.038* −0.039** −0.008 −0.012 −0.062*** −0.059***
(0.011) * (0.001) ** (0.454) (0.387) (0.001) *** (0.000) ***
after_covidTRUE −0.271*** −0.135*** −0.083*** −0.107*** −0.329*** −0.332***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
categoryresidential −0.060*** −0.037*** −0.048*** −0.031*** −0.061*** −0.063***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionEast of England 0.038* 0.040** 0.014 0.034* 0.019 0.032+
(0.016) * (0.002) ** (0.212) (0.016) * (0.325) (0.058) +
regionLondon 0.045** 0.055*** 0.002 −0.001 0.024 0.018
(0.004) ** (0.000) *** (0.834) (0.919) (0.209) (0.303)
regionNorth East 0.133*** 0.104*** 0.074*** 0.089*** 0.169*** 0.150***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionNorth West 0.062*** 0.063*** 0.020+ 0.039** 0.047* 0.046**
(0.000) *** (0.000) *** (0.068) + (0.006) ** (0.012) * (0.006) **
regionSouth East 0.085*** 0.047*** 0.038*** 0.050*** 0.042* 0.047**
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.014) * (0.002) **
regionSouth West 0.110*** 0.092*** 0.082*** 0.088*** 0.128*** 0.126***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionWest Midlands 0.007 0.018 −0.017 −0.002 −0.090*** −0.045**
(0.662) (0.142) (0.125) (0.892) (0.000) *** (0.008) **
regionYorkshire and The Humber −0.016 0.031* 0.036** 0.008 −0.036+ −0.029
(0.334) (0.018) * (0.003) ** (0.596) (0.066) + (0.105)
inheritedTRUE −0.045** −0.042*** −0.037*** −0.038** −0.051** −0.053**
(0.003) ** (0.001) *** (0.001) *** (0.005) ** (0.006) ** (0.001) **
Num.Obs. 12966 12931 12927 12953 12964 12942
R2 0.104 0.041 0.030 0.027 0.107 0.124
R2 Adj. 0.103 0.039 0.029 0.026 0.106 0.123
AIC 13271.6 7815.4 4933.2 10857.2 18399.2 15587.3
BIC 13398.6 7942.4 5060.2 10984.2 18526.2 15714.3
Log.Lik. −6618.794 −3890.704 −2449.623 −5411.619 −9182.592 −7776.674
RMSE 0.40 0.33 0.29 0.37 0.49 0.44
# run the model loops with nest() method
# add after_covid as control
# and interaction term
models_ols_inter <- socialcare %>% 
  group_by(domain) %>% 
  nest()%>% 
  mutate(ols_models = map(data, 
                          ~lm(rating_num ~ form * after_covid + 
                              category + region + inherited, 
                              data = .x))) %>% 
  mutate(results = map(ols_models, ~tidy(.x, conf.int = TRUE))) 

models_ols_inter_named <- models_ols_inter %>% 
  pull(ols_models, name = domain)
table_ols_inter <- modelsummary(models_ols_inter_named, statistic = "({p.value}) {stars}")
table_ols_inter
Safe Effective Caring Responsive Well-led Overall
(Intercept) 2.881*** 2.927*** 3.038*** 2.989*** 2.925*** 2.986***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
formNPO 0.044*** 0.019* 0.014+ 0.043*** 0.056*** 0.030*
(0.000) *** (0.030) * (0.073) + (0.000) *** (0.000) *** (0.018) *
formGOV 0.035 0.009 0.012 0.035+ 0.034 0.011
(0.134) (0.621) (0.464) (0.096) + (0.244) (0.664)
formCIC 0.036 0.001 0.026 0.032 0.047 0.028
(0.483) (0.986) (0.481) (0.481) (0.447) (0.614)
formIND −0.011 −0.026* −0.006 −0.008 −0.039+ −0.038*
(0.518) (0.050) * (0.632) (0.614) (0.060) + (0.040) *
after_covidTRUE −0.276*** −0.143*** −0.092*** −0.119*** −0.336*** −0.344***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
categoryresidential −0.059*** −0.037*** −0.048*** −0.031*** −0.061*** −0.063***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionEast of England 0.037* 0.039** 0.014 0.034* 0.018 0.032+
(0.017) * (0.002) ** (0.230) (0.017) * (0.342) (0.064) +
regionLondon 0.045** 0.055*** 0.002 −0.002 0.024 0.018
(0.004) ** (0.000) *** (0.843) (0.893) (0.207) (0.306)
regionNorth East 0.132*** 0.103*** 0.074*** 0.089*** 0.168*** 0.149***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionNorth West 0.062*** 0.063*** 0.021+ 0.039** 0.047* 0.046**
(0.000) *** (0.000) *** (0.063) + (0.005) ** (0.012) * (0.006) **
regionSouth East 0.085*** 0.046*** 0.038*** 0.049*** 0.042* 0.047**
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.015) * (0.002) **
regionSouth West 0.109*** 0.091*** 0.082*** 0.088*** 0.128*** 0.125***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionWest Midlands 0.006 0.018 −0.018 −0.002 −0.091*** −0.046**
(0.691) (0.157) (0.119) (0.867) (0.000) *** (0.007) **
regionYorkshire and The Humber −0.016 0.031* 0.035** 0.007 −0.037+ −0.029
(0.314) (0.021) * (0.003) ** (0.623) (0.063) + (0.100)
inheritedTRUE −0.045** −0.042*** −0.037*** −0.038** −0.051** −0.054**
(0.003) ** (0.001) *** (0.001) *** (0.005) ** (0.006) ** (0.001) **
formNPO × after_covidTRUE 0.055* 0.070*** 0.049* 0.086*** 0.056+ 0.088***
(0.020) * (0.001) *** (0.010) * (0.000) *** (0.050) + (0.001) ***
formGOV × after_covidTRUE 0.160** 0.124** 0.071+ 0.067 0.145* 0.176**
(0.002) ** (0.005) ** (0.076) + (0.181) (0.019) * (0.001) **
formCIC × after_covidTRUE 0.192+ 0.070 0.248** 0.023 0.156 0.215+
(0.059) + (0.424) (0.002) ** (0.818) (0.217) (0.058) +
formIND × after_covidTRUE −0.109** −0.075* −0.017 −0.027 −0.093* −0.084*
(0.001) ** (0.015) * (0.542) (0.446) (0.024) * (0.023) *
Num.Obs. 12966 12931 12927 12953 12964 12942
R2 0.106 0.043 0.032 0.028 0.108 0.126
R2 Adj. 0.105 0.041 0.030 0.027 0.107 0.125
AIC 13249.0 7796.5 4921.7 10849.4 18390.5 15564.4
BIC 13405.9 7953.3 5078.5 11006.3 18547.3 15721.2
Log.Lik. −6603.505 −3877.241 −2439.846 −5403.713 −9174.233 −7761.182
RMSE 0.40 0.33 0.29 0.37 0.49 0.44

Average Marginal Effects

For curvy fitted model line, the fitted coefficients is less meaningful than a average marginal effect concept.

Dr. Heiss has a very detailed blog post on this: https://www.andrewheiss.com/blog/2022/05/20/marginalia/

marginal_ols_inter <- models_ols_inter %>% 
  mutate(ame = map(ols_models,
                   ~ summary(marginaleffects(.)))) %>%
  mutate(nice_name = paste(domain, "ame"))
ame_ols_inter_named <- marginal_ols_inter %>% 
  pull(ame, name = nice_name)
table_ame_ols_inter <- tribble(
  ~domain, ~ame_df,
  "safe",  ame_ols_inter_named[["Safe ame"]],
  "effective", ame_ols_inter_named[["Effective ame"]],
  "caring",  ame_ols_inter_named[["Caring ame"]],
  "responsive", ame_ols_inter_named[["Responsive ame"]],
  "well-led",  ame_ols_inter_named[["Well-led ame"]],
  "overall", ame_ols_inter_named[["Overall ame"]]
) %>% 
  unnest(ame_df) %>% 
  filter(term == "form")

table_ame_ols_inter
## # A tibble: 24 × 10
##    domain   type  term  contr…¹ estim…² std.e…³ stati…⁴ p.value conf.low conf.…⁵
##    <chr>    <chr> <chr> <chr>     <dbl>   <dbl>   <dbl>   <dbl>    <dbl>   <dbl>
##  1 safe     resp… form  NPO - …  0.0595 0.0101    5.89  3.78e-9  0.0397   0.0793
##  2 safe     resp… form  GOV - …  0.0816 0.0214    3.82  1.33e-4  0.0398   0.123 
##  3 safe     resp… form  CIC - …  0.0914 0.0445    2.05  3.99e-2  0.00421  0.179 
##  4 safe     resp… form  IND - … -0.0426 0.0149   -2.86  4.20e-3 -0.0718  -0.0134
##  5 effecti… resp… form  NPO - …  0.0347 0.00815   4.26  2.01e-5  0.0188   0.0507
##  6 effecti… resp… form  GOV - …  0.0365 0.0171    2.14  3.26e-2  0.00303  0.0700
##  7 effecti… resp… form  CIC - …  0.0160 0.0360    0.445 6.57e-1 -0.0545   0.0865
##  8 effecti… resp… form  IND - … -0.0426 0.0121   -3.52  4.30e-4 -0.0663  -0.0189
##  9 caring   resp… form  NPO - …  0.0243 0.00729   3.34  8.50e-4  0.0100   0.0386
## 10 caring   resp… form  GOV - …  0.0268 0.0153    1.75  7.99e-2 -0.00319  0.0568
## # … with 14 more rows, and abbreviated variable names ¹​contrast, ²​estimate,
## #   ³​std.error, ⁴​statistic, ⁵​conf.high
# commented out for the moment
# table_ols_inter <- modelsummary(ame_ols_inter_named, statistic = "({p.value}) {stars}")
#table_ols_inter

The gap of before vs. after covid rating (before is higher) is larger for for-profit smaller for NPO, GOV, which is consistent with the NYT articles

update: more complex when interpreting non-linear marginal effects http://datacolada.org/57

Running logit models

# run the model loops with nest() method
models_logit <- socialcare %>% 
  group_by(domain) %>% 
  nest()%>% 
  mutate(logit_models = map(data, 
                          ~glm(rating_higher ~ form + 
                              category + region + inherited , 
                              data = .x,  family = binomial(link = "logit")))) %>% 
  mutate(results = map(logit_models, ~tidy(.x, conf.int = TRUE))) 

models_logit_named <- models_logit %>% 
  pull(logit_models, name = domain)
table_logit <- modelsummary(models_logit_named, statistic = "({p.value}) {stars}")
table_logit
Safe Effective Caring Responsive Well-led Overall
(Intercept) 1.413*** 2.098*** 3.480*** 2.470*** 1.250*** 1.637***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
formNPO 0.594*** 0.492*** 0.814*** 0.739*** 0.586*** 0.635***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
formGOV 0.669*** 0.323 1.036* 1.010*** 0.501*** 0.578***
(0.000) *** (0.107) (0.023) * (0.001) *** (0.001) *** (0.001) ***
formCIC 0.614 0.134 0.146 0.397 0.062 0.446
(0.102) (0.755) (0.840) (0.442) (0.827) (0.235)
formIND −0.108 −0.196+ 0.287 0.235+ −0.090 −0.099
(0.240) (0.085) + (0.167) (0.096) + (0.300) (0.300)
categoryresidential −0.416*** −0.457*** −0.945*** −0.565*** −0.313*** −0.473***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionEast of England 0.300** 0.414*** 0.172 0.193 0.116 0.258*
(0.002) ** (0.001) *** (0.337) (0.147) (0.204) (0.011) *
regionLondon 0.299** 0.595*** 0.506* 0.136 0.287** 0.288**
(0.002) ** (0.000) *** (0.013) * (0.313) (0.003) ** (0.006) **
regionNorth East 0.890*** 0.974*** 1.046** 0.876*** 0.835*** 0.868***
(0.000) *** (0.000) *** (0.002) ** (0.000) *** (0.000) *** (0.000) ***
regionNorth West 0.451*** 0.540*** 0.546** 0.372** 0.375*** 0.430***
(0.000) *** (0.000) *** (0.004) ** (0.006) ** (0.000) *** (0.000) ***
regionSouth East 0.616*** 0.400*** 0.769*** 0.459*** 0.322*** 0.453***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionSouth West 0.875*** 0.988*** 1.009*** 0.830*** 0.841*** 0.926***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionWest Midlands 0.135 0.245* −0.129 0.208 −0.289*** −0.051
(0.148) (0.035) * (0.440) (0.117) (0.001) *** (0.593)
regionYorkshire and The Humber −0.048 0.303* 0.931*** 0.168 −0.069 −0.019
(0.618) (0.014) * (0.000) *** (0.225) (0.461) (0.849)
inheritedTRUE −0.152 −0.271* −0.436* −0.203 −0.012 −0.060
(0.118) (0.021) * (0.013) * (0.124) (0.897) (0.563)
Num.Obs. 12966 12931 12927 12953 12964 12942
AIC 11637.2 7964.7 3754.4 6816.5 12929.5 10856.6
BIC 11749.2 8076.7 3866.4 6928.5 13041.6 10968.6
Log.Lik. −5803.591 −3967.352 −1862.184 −3393.241 −6449.765 −5413.289
RMSE 0.37 0.29 0.18 0.26 0.40 0.36
# run the model loops with nest() method
models_logit_covid <- socialcare %>% 
  group_by(domain) %>% 
  nest()%>% 
  mutate(logit_models = map(data, 
                          ~glm(rating_higher ~ form + after_covid +
                              category + region + inherited , 
                              data = .x,  family = binomial(link = "logit")))) %>% 
  mutate(results = map(logit_models, ~tidy(.x, conf.int = TRUE))) 

models_logit_covid_named <- models_logit_covid %>% 
  pull(logit_models, name = domain)
table_logit_covid <- modelsummary(models_logit_covid_named, statistic = "({p.value}) {stars}")
table_logit_covid
Safe Effective Caring Responsive Well-led Overall
(Intercept) 2.047*** 2.505*** 4.101*** 2.860*** 1.867*** 2.552***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
formNPO 0.461*** 0.418*** 0.733*** 0.677*** 0.462*** 0.469***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
formGOV 0.533** 0.253 0.947* 0.949** 0.374* 0.422*
(0.002) ** (0.214) (0.039) * (0.001) ** (0.015) * (0.022) *
formCIC 0.574 0.125 0.238 0.409 −0.055 0.336
(0.139) (0.774) (0.747) (0.433) (0.854) (0.396)
formIND −0.241* −0.272* 0.219 0.181 −0.217* −0.282**
(0.012) * (0.019) * (0.300) (0.207) (0.018) * (0.006) **
after_covidTRUE −1.484*** −1.211*** −1.585*** −1.168*** −1.478*** −1.944***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
categoryresidential −0.410*** −0.476*** −0.986*** −0.589*** −0.303*** −0.475***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionEast of England 0.263** 0.411*** 0.150 0.187 0.065 0.212+
(0.009) ** (0.001) *** (0.413) (0.166) (0.499) (0.052) +
regionLondon 0.309** 0.631*** 0.514* 0.167 0.306** 0.321**
(0.003) ** (0.000) *** (0.013) * (0.225) (0.002) ** (0.004) **
regionNorth East 1.020*** 1.110*** 1.205*** 1.004*** 0.977*** 1.086***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionNorth West 0.464*** 0.548*** 0.529** 0.372** 0.385*** 0.455***
(0.000) *** (0.000) *** (0.006) ** (0.007) ** (0.000) *** (0.000) ***
regionSouth East 0.586*** 0.389*** 0.744*** 0.455*** 0.272** 0.410***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.002) ** (0.000) ***
regionSouth West 0.845*** 0.990*** 0.962*** 0.814*** 0.822*** 0.914***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionWest Midlands 0.064 0.238* −0.180 0.182 −0.403*** −0.173+
(0.515) (0.045) * (0.293) (0.176) (0.000) *** (0.097) +
regionYorkshire and The Humber −0.072 0.321* 0.955*** 0.171 −0.094 −0.047
(0.476) (0.011) * (0.000) *** (0.224) (0.338) (0.667)
inheritedTRUE −0.355*** −0.398*** −0.584** −0.309* −0.203* −0.347**
(0.000) *** (0.001) *** (0.001) ** (0.021) * (0.037) * (0.002) **
Num.Obs. 12966 12931 12927 12953 12964 12942
AIC 10728.5 7619.0 3511.9 6553.3 11911.2 9452.6
BIC 10848.1 7738.5 3631.4 6672.8 12030.7 9572.1
Log.Lik. −5348.271 −3793.515 −1739.959 −3260.636 −5939.585 −4710.319
RMSE 0.36 0.29 0.18 0.26 0.38 0.33
# run the model loops with nest() method
models_logit_inter <- socialcare %>% 
  group_by(domain) %>% 
  nest()%>% 
  mutate(logit_models = map(data, 
                          ~glm(rating_higher ~ form * after_covid +
                              category + region + inherited , 
                              data = .x,  family = binomial(link = "logit")))) %>% 
  mutate(results = map(logit_models, ~tidy(.x, conf.int = TRUE))) 

models_logit_inter_named <- models_logit_inter %>% 
  pull(logit_models, name = domain)
table_logit_inter <- modelsummary(models_logit_inter_named, statistic = "({p.value}) {stars}")
table_logit_inter
Safe Effective Caring Responsive Well-led Overall
(Intercept) 2.033*** 2.523*** 4.100*** 2.863*** 1.856*** 2.543***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
formNPO 0.510*** 0.307* 0.644** 0.563*** 0.507*** 0.515***
(0.000) *** (0.012) * (0.007) ** (0.000) *** (0.000) *** (0.000) ***
formGOV 0.348 0.025 0.534 1.012** 0.303 0.215
(0.103) (0.914) (0.297) (0.009) ** (0.114) (0.375)
formCIC 0.430 −0.132 −0.035 0.461 −0.285 0.016
(0.409) (0.799) (0.973) (0.523) (0.415) (0.976)
formIND −0.097 −0.221 0.506 0.336+ −0.117 −0.175
(0.453) (0.133) (0.124) (0.079) + (0.328) (0.238)
after_covidTRUE −1.459*** −1.251*** −1.585*** −1.171*** −1.457*** −1.931***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
categoryresidential −0.407*** −0.475*** −0.982*** −0.589*** −0.302*** −0.472***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionEast of England 0.262** 0.408** 0.144 0.185 0.064 0.211+
(0.009) ** (0.001) ** (0.430) (0.172) (0.508) (0.053) +
regionLondon 0.313** 0.632*** 0.517* 0.164 0.310** 0.325**
(0.002) ** (0.000) *** (0.012) * (0.231) (0.002) ** (0.004) **
regionNorth East 1.018*** 1.108*** 1.204*** 1.000*** 0.975*** 1.084***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionNorth West 0.460*** 0.551*** 0.530** 0.373** 0.382*** 0.453***
(0.000) *** (0.000) *** (0.006) ** (0.006) ** (0.000) *** (0.000) ***
regionSouth East 0.587*** 0.386*** 0.742*** 0.453*** 0.273** 0.412***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.002) ** (0.000) ***
regionSouth West 0.846*** 0.987*** 0.957*** 0.812*** 0.825*** 0.917***
(0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) *** (0.000) ***
regionWest Midlands 0.063 0.234* −0.182 0.184 −0.403*** −0.174+
(0.520) (0.049) * (0.286) (0.173) (0.000) *** (0.096) +
regionYorkshire and The Humber −0.076 0.317* 0.948*** 0.167 −0.097 −0.050
(0.453) (0.012) * (0.000) *** (0.235) (0.325) (0.649)
inheritedTRUE −0.352*** −0.399*** −0.584** −0.312* −0.202* −0.345**
(0.001) *** (0.001) *** (0.001) ** (0.020) * (0.039) * (0.002) **
formNPO × after_covidTRUE −0.108 0.322 0.202 0.345 −0.108 −0.086
(0.497) (0.132) (0.580) (0.178) (0.468) (0.619)
formGOV × after_covidTRUE 0.491 0.750 1.296 −0.164 0.191 0.432
(0.176) (0.109) (0.254) (0.787) (0.544) (0.233)
formCIC × after_covidTRUE 0.300 0.679 0.510 −0.111 0.646 0.631
(0.695) (0.460) (0.727) (0.915) (0.288) (0.413)
formIND × after_covidTRUE −0.343+ −0.156 −0.548 −0.392 −0.259 −0.223
(0.081) + (0.518) (0.204) (0.177) (0.171) (0.285)
Num.Obs. 12966 12931 12927 12953 12964 12942
AIC 10730.9 7620.9 3516.1 6557.2 11915.2 9457.0
BIC 10880.3 7770.3 3665.4 6706.6 12064.6 9606.4
Log.Lik. −5345.437 −3790.460 −1738.042 −3258.601 −5937.599 −4708.518
RMSE 0.36 0.29 0.18 0.26 0.38 0.33