Measuring Mental Health Quality of Life in R: A Psychometric Evaluation and Standardised MHQoL Toolbox

Stijn Image

Erasmus School of Health, Policy & Management (ESHPM)

Email: s.b.peeters@eshpm.eur.nl

Phone:+316-34404346

🧠 Why Standardised Scoring and Psychometric Evaluation Matter

  • ✅ Validated health instruments (like MHQoL) are essential in health research
  • ❌ Manual scoring is error-prone and inefficient
  • Psychometric evaluation ensures:
    • Internal consistency
    • Validity (construct & convergent)
  • ⚙️ R enables:
    • Automated scoring
    • Reproducible evaluation

📦 What this Project Delivers

  • 📊 Psychometric analysis workflow in R
  • Custom R package for:
    • MHQoL score recalculation
    • Consistent scoring logic
  • 🌐 Interactive Shiny App for:
    • User-friendly input
    • Automated results & visualisation
  • 🔁 Fully reproducible pipeline

♻️ Integrated Workflow: From Data to Results

  1. 📄 Collect MHQoL Responses
  2. ⚙️ Recalculate Scores Using R Package or Shiny App
  3. 🖥️ Use Shiny App for Visual Summary
  4. 📈 Run Psychometric Analysis in R
  5. 📝 Interpret and Report Results

⚙️ Recalculate Scores Using R Package or Shiny App

📦 R Package

💻 Shiny interface

🧠 What is the MHQoL?

  • A 7-item questionnaire for mental health-related quality of life

  • Includes a Visual Analogue Scale (VAS) for overall mental well-being

💡 Why use it — especially next to the EQ-5D?

  • The EQ-5D focuses primarily on physical health

  • MHQoL captures additional aspects such as mood, relationships, and future outlook

  • Offers a more complete picture of wellbeing in mental health populations

  • Supports richer outcome measurement in evaluations and research

⚙️ Recalculate Scores Using the MHQoL Package

  • 🗂️ Contains 8 function, highlight two:
    • mhqol()
    • mhqol_LSS()
  • 📑 One dataframe:
    • mhqol_valueset()
  • 🖥️ Shiny Tool is integrated in the package
    • shiny_mhqol()

⚙️

🧮 Input in Scores

ID Group SI IN MO RE DA PH FU
1 Group B 2 0 2 3 2 1 3
2 Group A 1 2 0 2 1 0 3
3 Group A 2 2 3 3 3 0 0
4 Group B 3 0 0 3 0 1 0
5 Group B 2 2 3 0 1 3 2
6 Group B 3 1 1 1 2 2 2

📝 Input in Text

ID Group SI IN MO RE DA PH FU
1 Group B I think positively about myself I am dissatisfied with my level of independence I feel a little anxious, gloomy, or depressed I am very dissatisfied with my relationships I am dissatisfied with my daily activities I have no physical health problems I am very optimistic about my future
2 Group B I think positively about myself I am very dissatisfied with my level of independence I feel anxious, gloomy, or depressed I am satisfied with my relationships I am satisfied with my daily activities I have a great many physical health problems I am optimistic about my future
3 Group A I think very negatively about myself I am very dissatisfied with my level of independence I feel very anxious, gloomy, or depressed I am very satisfied with my relationships I am dissatisfied with my daily activities I have some physical health problems I am very optimistic about my future
4 Group B I think very positively about myself I am very satisfied with my level of independence I feel anxious, gloomy, or depressed I am very satisfied with my relationships I am satisfied with my daily activities I have a great many physical health problems I am optimistic about my future
5 Group B I think positively about myself I am very dissatisfied with my level of independence I feel very anxious, gloomy, or depressed I am very dissatisfied with my relationships I am satisfied with my daily activities I have many physical health problems I am very gloomy about my future
6 Group B I think very negatively about myself I am dissatisfied with my level of independence I feel anxious, gloomy, or depressed I am dissatisfied with my relationships I am dissatisfied with my daily activities I have no physical health problems I am optimistic about my future

Which to use? 🤔

Both! 🥳

Example - Output in utilities?🤔

library(MHQoL)

# Prepare input: 7 MHQoL dimensions
dimensions <- example_data_scores[, c("SI", "IN", "MO", "RE", "DA", "PH", "FU")]

# Calculate total utility score (Netherlands value set)
mhqol_utility <- mhqol(
  dimensions = dimensions,
  country = "Netherlands",   # 🇳🇱 Default option
  metric = "total",          # "total" or "average"
  ignore_invalid = TRUE,     # Skip incomplete rows
  ignore_NA = FALSE          # Stop if NAs are present
)
SI_u IN_u MO_u RE_u DA_u PH_u FU_u utility
-0.007 -0.184 -0.063 0.000 -0.021 -0.243 0.00 0.482
-0.137 -0.018 -0.311 -0.015 -0.140 -0.383 0.00 -0.004
-0.007 -0.018 0.000 0.000 0.000 -0.383 -0.17 0.422
0.000 -0.184 -0.311 0.000 -0.213 -0.243 -0.17 -0.121
-0.007 -0.018 0.000 -0.269 -0.140 0.000 0.00 0.566
0.000 -0.118 -0.179 -0.172 -0.021 -0.064 0.00 0.446

Example - Output in scores?🤔

library(MHQoL)

# Prepare input: 7 MHQoL dimensions
dimensions <- example_data_text[, c("SI", "IN", "MO", "RE", "DA", "PH", "FU")] #Input from the text dataframe

# Calculate total utility score (Netherlands value set)
mhqol_LSS <- mhqol_LSS(
  dimensions = dimensions,
  metric = "total",          # "total" or "average"
  ignore_invalid = TRUE,     # Skip incomplete rows
  ignore_NA = FALSE          # Stop if NAs are present
)
SI_s IN_s MO_s RE_s DA_s PH_s FU_s LSS
2 1 2 0 1 3 3 12
2 0 1 2 2 0 2 9
0 0 0 3 1 2 3 9
3 3 1 3 2 0 2 14
2 0 0 0 2 1 0 5
0 1 1 1 1 3 2 9

Or if you want to use an Interface (from Shiny): the MHQoL cooker👩‍🍳

::: :::

📈 The actual work starts: run the Psychometric Analysis in R

  1. Internal Consistency
    • Cronbach’s Alpha
  2. Construct Validity
    • Measurement invariance test
    • Spearman’s Rank Correlation Coefficients
    • Multilevel Regression Analyses
  3. Convergent Validity
    • Spearman’s Rank Correlation Coefficients

Internal Consistency using the ltm package

⚙️ How We Used It

library(ltm)

# Select MHQoL dimensions (7 items)
dimensions <- example_data_scores[, c("SI", "IN", "MO", "RE", "DA", "PH", "FU")]

# Compute Cronbach’s Alpha
cronbach.alpha(dimensions)

🧠 Why we used it?

  • Simple and dedicated function for Cronbach’s Alpha
  • Integrated in a package already suited for psychometric analysis
  • Output includes:
    • Overall alpha
    • Item-total correlations
    • Effect of removing each item
  • Ideal for Likert-style or binary questionnaire items
  • Lightweight and easy to interpret — perfect for streamlined reporting

🔍 Measurement invariance - Why Test Measurement Invariance?

🧠 Purpose

  • Ensure MHQoL measures the same construct across groups
  • Without it, comparisons may be biased or invalid

🔬 Invariance Levels

  1. Configural: Same structure
  2. Metric: Equal loadings
  3. Scalar: Equal loadings + intercepts
  4. (Optional) Residual: Equal residual variances

  • Each step adds constraints and tests whether the model still fits well.

✅ Sow we Tested it in R (lavaan)

library(lavaan)

# Latent model: 1 factor with 7 observed MHQoL items
model <- '
  MHQoL =~ SI + IN + MO + RE + DA + PH + FU
'

# 1. Configural invariance
fit_config <- cfa(model, data = df, group = "group_var",
                  estimator = "WLSMV", ordered = TRUE)

# 2. Metric invariance (equal loadings)
fit_metric <- cfa(model, data = df, group = "group_var",
                  estimator = "WLSMV", ordered = TRUE,
                  group.equal = "loadings")

# 3. Scalar invariance (equal loadings + intercepts)
fit_scalar <- cfa(model, data = df, group = "group_var",
                  estimator = "WLSMV", ordered = TRUE,
                  group.equal = c("loadings", "intercepts"))

# Compare model fits
anova(fit_config, fit_metric, fit_scalar)

📊 Comparing Invariance Models

Model CFI RMSEA SRMR
Configural 0.99 0.04 0.06
Metric 0.99 0.04 0.07
Scalar 0.96 0.10 0.07
Partial scalar 0.99 0.03 0.06

Partial scalar: free some intercepts, for example

fit_part_scalar <- cfa(model, data = df, group = "group_var",
                  estimator = "WLSMV", ordered = TRUE,
                  group.equal = c("loadings", C("SI|T1", "IN|T2")))

🔗 Spearman’s Rank Correlation Coefficients

🧠 Purpose

  • Assess convergent validity between MHQoL and related health measures
  • Spearman’s rank correlation is:
    • Non-parametric
    • Based on ranked values
    • Ideal for ordinal or non-normal data
  • ✅ In R, correlation methods are available with cor.test() (also for pearson)

📌 Example Use Cases: MHQoL vs. EQ-5D

# Pearson
cor.test(x = mhqol_score, y = eq5d_score, method = "pearson")

# Spearman
cor.test(x = mhqol_score, y = eq5d_score, method = "spearman")

📊 Example output correlations with MHQoL Score

Variable Spearman’s ρ p-value
EQ-5D LSS 0.62 < 0.001
WHO-5 Wellbeing 0.58 < 0.001
PHQ-9 (depression) -0.55 < 0.001

Last step👣: Multilevel regression

🌍 Data Structure

  • Individuals are nested within countries
  • Ignoring this would violate independence assumptions

🎯 Research Questions

  1. Do MHQoL dimensions predict self-reported mental QoL (MHQoL-VAS)?
  2. Do EQ-5D-5L dimensions explain mental QoL differences?

📐 Methodological Approach

  • Used multilevel regression to account for hierarchy
  • Included:
    • Fixed effects for predictors
    • Covariates: age and gender (sex assigned at birth)

🧪 Compared two model types:

  1. Random Intercept Model
    – Intercepts vary across countries

  2. Random Intercept + Slope Model
    – Both intercepts and slopes vary across countries

  • Likelihood ratio test** favored random intercept only

How it was done in R

library(lme4)

# Random intercept model: MHQoL dimensions → MHQoL-VAS
model1 <- lmer(
  mhqol_vas ~ SI + IN + MO + RE + DA + PH + FU +
  age + gender + (1 | country),
  data = example_data_scores
)

# Random intercept + slope model (example: FU varies by country)
model2 <- lmer(
  mhqol_vas ~ SI + IN + MO + RE + DA + PH + FU +
  age + gender + (FU | country),
  data = example_data_scores
)

# Compare models
anova(model1, model2)

# Model performance
summary(model1)

✅ Key Takeaways

  • 🧠 R provides a complete psychometric workflow, from internal consistency to measurement invariance and multilevel modeling

  • 📦 We used specialized packages:

    • ltm for Cronbach’s Alpha
    • lavaan for Confirmatory Factor Analysis and Measurement Invariance
    • lme4 for Multilevel Regression
  • 🧰 We developed the MHQoL R package and Shiny app:

    • Standardized scoring
    • Enhances reproducibility and ease of use
  • 🎯 Together, these tools support both rigorous evaluation and practical implementation of mental health QoL measures

Any Questions?

The MHQoL R package and Shiny app streamline scoring, reduce manual errors, and make validated mental health quality of life measurement more accessible and reproducible.