# Libraries
library(tidyr)
library(dplyr)
library(ggplot2)
library(lubridate)
library(plotly)
library(table1)
library(REDCapR)
library(Hmisc)
library(RColorBrewer)
library(stringr)
library(knitr)
library(kableExtra)
# Functions
# Replace blank with NA
replace_blank_with_na <- function(x) {
if (is.character(x)) {
x <- na_if(x, "")
}
return(x)
}
Due to increasing demand for mental health services and ongoing limitations in access to specialty care, primary care providers (PCPs) are increasingly required to manage complex pediatric mental health concerns. The COVID-19 pandemic has intensified these demands, highlighting gaps in support for PCPs who work with children and youth. Simultaneously, Ontario faces a growing primary care human resources crisis, with millions of residents lacking connection to a regular PCP. In this context, PCPs require increased support, resources, and training to meet patient needs effectively.
Although collaborative care models and pediatric mental health education initiatives have been implemented internationally and across North America, there is limited evaluation in Canadian settings. Existing studies suggest that PCPs benefit most from a range of educational formats, from brief workshops to sustained consultation models. However, few Canadian programs have assessed these training needs across different settings or in a post-pandemic landscape.
This project represents the first phase of a two-step needs assessment aimed at informing pediatric mental health education program development in Ontario. The primary objective is to survey PCPs across the province to understand their:
This summary highlights the results of the electronic survey component, analyzing both quantitative and qualitative responses to inform future education planning and system improvements.
All data and visualizations were compiled by Hassan Abdulrasul, For detailed insights into the methodology or specific code implementations, please contact (hassan.abdulrasul@camh.ca).
Participants were asked to identify their professional role, gender identity, and years in practice. The figures below show the distribution of providers who responded to the survey.
| Overall (N=27) |
|
|---|---|
| Provider Role | |
| Family physician | 9 (33.3%) |
| Nurse practitioner | 4 (14.8%) |
| Other - Addictions counsellor | 1 (3.7%) |
| Other - Case worker | 1 (3.7%) |
| Other - Youth Addiction Counsellor | 1 (3.7%) |
| Pediatrician | 2 (7.4%) |
| Psychiatrist | 1 (3.7%) |
| Registered nurse | 4 (14.8%) |
| Social worker | 4 (14.8%) |
| Gender | |
| Man | 8 (29.6%) |
| Woman | 19 (70.4%) |
| Duration of Practice | |
| Under 5 years | 5 (18.5%) |
| Between 5 and 15 years | 11 (40.7%) |
| Over 15 years | 11 (40.7%) |
These histograms show the number of providers working in each type of practice setting and location. Respondents could select multiple options.
# Wrangle: count selected location options
location_counts <- NEEDS_Merged %>%
select(starts_with("nas_setting_location")) %>%
summarise(across(everything(), ~ sum(. == 1, na.rm = TRUE))) %>%
pivot_longer(cols = everything(), names_to = "Location", values_to = "Count") %>%
mutate(Location = recode(Location,
"nas_setting_location___1" = "Urban",
"nas_setting_location___2" = "Suburban",
"nas_setting_location___3" = "Rural",
"nas_setting_location___4" = "Remote"))
# Plot
plot_ly(location_counts,
x = ~Location,
y = ~Count,
type = 'bar',
text = ~Count,
textposition = "auto",
marker = list(color = RColorBrewer::brewer.pal(n = 4, "Pastel1")),
hoverinfo = 'text') %>%
layout(
title = list(
text = "Practice Location Distribution",
x = 0.5,
font = list(size = 20)
),
annotations = list(
list(
x = 0.5,
y = 1.1,
text = "<i>Q. Please select from the following based on your practice setting:</i>",
xref = "paper",
yref = "paper",
xanchor = "center",
showarrow = FALSE,
font = list(size = 14, color = "gray")
)
),
xaxis = list(title = "", tickfont = list(size = 14)),
yaxis = list(title = "Number of Respondents", tickfont = list(size = 14)),
margin = list(b = 80, t = 100, l = 60, r = 40),
showlegend = FALSE
)
These histograms show the number of providers working in each type of practice setting and location. Respondents could select multiple options.
Participants were also able to provide free-text responses - these responses are presented verbatim on the table below
# Count selections for each setting type
setting_type_counts <- NEEDS_Merged %>%
select(starts_with("nas_setting_type")) %>%
summarise(across(everything(), ~ sum(. == 1, na.rm = TRUE))) %>%
pivot_longer(cols = everything(), names_to = "Setting", values_to = "Count") %>%
mutate(Setting = recode(Setting,
"nas_setting_type___1" = "Community setting",
"nas_setting_type___2" = "Hospital-based setting",
"nas_setting_type___3" = "Other setting"
))
plot_ly(setting_type_counts,
x = ~Setting,
y = ~Count,
type = 'bar',
text = ~Count,
textposition = "auto",
marker = list(color = RColorBrewer::brewer.pal(n = 3, "Pastel2")),
hoverinfo = 'text') %>%
layout(
title = list(
text = "Practice Setting Type",
x = 0.5,
font = list(size = 20)
),
annotations = list(
list(
x = 0.5,
y = 1.1,
text = "<i>Q. Please select from the following based on your practice setting (type):</i>",
xref = "paper",
yref = "paper",
xanchor = "center",
showarrow = FALSE,
font = list(size = 14, color = "gray")
)
),
xaxis = list(title = "", tickfont = list(size = 14)),
yaxis = list(title = "Number of Respondents", tickfont = list(size = 14)),
margin = list(b = 80, t = 100, l = 60, r = 40),
showlegend = FALSE
)
# Construct themed quote table
setting_themed_quotes <- tibble::tibble(
Theme = c("Home-based care", "Long-Term Care"),
Quote = c(
"In client home as well",
"LONG-TERM CARE"
)
)
# Render with kableExtra
setting_themed_quotes %>%
kbl(caption = "Provider Comments on 'Other' Practice Settings") %>%
kable_styling(
full_width = FALSE,
bootstrap_options = c("hover", "condensed", "striped"),
position = "center"
) %>%
column_spec(1, bold = TRUE, width = "30%") %>%
column_spec(2, width = "70%")
| Theme | Quote |
|---|---|
| Home-based care | In client home as well |
| Long-Term Care | LONG-TERM CARE |
Participants were asked to indicate the age ranges they work with and to estimate what proportion of their patient base falls within specific demographic groups or presents with mental health concerns.
:
Providers rated agreement with statements about various mental health service delivery gaps, including access to psychotherapy, psychiatric consultation, and family supports. The chart below presents the distribution of responses by area of need.
Each Statement was rated from 1-5 (Strongly disagree - Strongly Agree)
In addition to rating predefined service options, providers offered open-text comments about embedded and additional services that would support their patients. Key themes include improving access to psychiatry, embedding psychotherapy and counselling supports within practice settings, addressing school and family needs, and increasing availability of community and crisis services.
| Theme | Quote |
|---|---|
| Service Coordination and Resources | Disjointed services in the county…… Having school collaboration |
| Therapy Access | Providing therapy sessions. |
| School-Based Mental Health | Supports within the school environment. Addressing social issues such as bullying in the school environment. |
| Trauma / Long-Term Therapy / Geography | Specifically trauma therapy, and DBT… Psychotherapy options are limited to short-term, and access to psychiatrists or counselors often requires traveling 1.5 hours. |
| Access to OHIP-Covered Psychological Services | Timely access to OHIP-covered services provided by clinical psychologists, e.g., autism assessment, ADHD support, DBT. |
| Theme | Quote |
|---|---|
| Access to Psychiatry & Psychology | Psychiatry or psychology for complex cases… or community support teams that actually pick up referrals……Evening services when families can drive and attend |
| Embedded Therapy & Counselling Teams | On-site psychotherapy would be ideal… most youth come to the hospital for this but it isn’t offered. |
| School/Family Support Integration | Social work, psychotherapists, and case workers to help families address school-related concerns. |
| Community Navigation / Support Teams | For easy access… individuals can access support without needing specialized clinics. |
| Reducing Stigma & Early Intervention | Early identification and intervention, reduced stigma, accessibility. |
| On-site Programs & Crisis Services | Groups, therapy, counselling services, crisis lines, psychiatrist in-office. |
Providers identified training interests across a range of pediatric mental health topics, including substance use, trauma, neurodevelopmental disorders, and more. Additional items captured interest in specific areas such as medication management and psychosocial interventions.
| Theme | Quote |
|---|---|
| Emotion Regulation & DBT for Youth | DBT/emotion regulation aimed for children & youth. |
| Support for Refugee Children | Help for refugee children to gain access to schooling and supports (psychoeducational assessments). |
sud_labels <- c(
nas_education_sud___1 = "Alcohol",
nas_education_sud___2 = "Nicotine",
nas_education_sud___3 = "Cannabis",
nas_education_sud___4 = "Benzodiazepines",
nas_education_sud___5 = "Opioids",
nas_education_sud___6 = "Other"
)
edu_sud <- NEEDS_Education %>%
select(starts_with("nas_education_sud___")) %>%
pivot_longer(cols = everything(), names_to = "topic", values_to = "selected") %>%
filter(selected == 1) %>%
mutate(topic = recode(topic, !!!sud_labels)) %>%
count(topic) %>%
arrange(desc(n))
plot_ly(edu_sud,
x = ~topic,
y = ~n,
type = 'bar',
text = ~n,
textposition = "auto",
marker = list(color = "mediumpurple"),
hoverinfo = 'text') %>%
layout(
title = list(text = "Substance Use Disorder Education Interests", x = 0.5),
annotations = list(
list(
x = 0.5,
y = 1.1,
text = "<i>Q. If interested in Substance Use Disorders education/training initiatives:",
xref = "paper",
yref = "paper",
xanchor = "center",
showarrow = FALSE,
font = list(size = 14, color = "gray")
)
),
xaxis = list(title = "", tickangle = -30, tickfont = list(size = 12)),
yaxis = list(title = "Count", titlefont = list(size = 16)),
margin = list(b = 100, t = 100, l = 60, r = 40),
showlegend = FALSE
)
sud_other_final <- tibble::tibble(
Theme = c(
"Non-Substance Behavioral Issues",
"Emerging / Non-traditional Substances"
),
Quote = c(
"Food",
"\"Magic mushrooms\", cocaine, methamphetamine"
)
)
sud_other_final %>%
kbl(caption = "Other Substance Use Education Interests") %>%
kable_styling(
full_width = FALSE,
bootstrap_options = c("hover", "striped", "condensed"),
position = "center"
) %>%
column_spec(1, bold = TRUE, width = "35%") %>%
column_spec(2, width = "65%")
| Theme | Quote |
|---|---|
| Non-Substance Behavioral Issues | Food |
| Emerging / Non-traditional Substances | “Magic mushrooms”, cocaine, methamphetamine |
add_labels <- c(
nas_education2___1 = "Medication for mental health management (youth)",
nas_education2___2 = "Brief psychosocial interventions (CBT, etc.)",
nas_education2___3 = "Measurement-based care for treatment and response",
nas_education2___4 = "Other"
)
edu_additional <- NEEDS_Education %>%
select(starts_with("nas_education2___")) %>%
pivot_longer(cols = everything(), names_to = "topic", values_to = "selected") %>%
filter(selected == 1) %>%
mutate(topic = recode(topic, !!!add_labels)) %>%
count(topic) %>%
arrange(desc(n))
plot_ly(edu_additional,
x = ~n,
y = ~topic,
type = 'bar',
orientation = 'h',
text = ~n,
textposition = "auto",
marker = list(color = "seagreen"),
hoverinfo = 'text') %>%
layout(
title = list(text = "Additional Education Topics of Interest", x = 0.5),
annotations = list(
list(
x = 0.22,
y = 1.1,
text = "<i>Q. I am additionally interested in education/training initiatives in:</i>",
xref = "paper",
yref = "paper",
xanchor = "center",
showarrow = FALSE,
font = list(size = 14, color = "gray")
)
),
xaxis = list(title = "Count"),
yaxis = list(title = "", automargin = TRUE, tickfont = list(size = 14)),
margin = list(l = 200, t = 100, r = 40, b = 60),
showlegend = FALSE
)
Participants were asked to indicate their preferred learning formats for future capacity-building. The stacked bar chart below illustrates the distribution of preferences across formats such as case-based discussions, webinars, and self-directed modules.
format_labels <- c(
nas_format1 = "Self-directed online learning modules",
nas_format2 = "Case-based discussions",
nas_format3 = "Seminars / webinars",
nas_format4 = "Other format"
)
format_long <- NEEDS_Education %>%
select(nas_format1:nas_format4) %>%
pivot_longer(cols = everything(), names_to = "format", values_to = "response") %>%
filter(!is.na(response)) %>%
mutate(
format = recode(format, !!!format_labels),
response = factor(response, levels = 1:5,
labels = c("Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"))
)
format_dist <- format_long %>%
count(format, response) %>%
group_by(format) %>%
mutate(percent = n / sum(n) * 100)
likert_colors <- RColorBrewer::brewer.pal(5, "RdYlBu")
plot_ly(format_dist,
x = ~percent,
y = ~format,
type = 'bar',
color = ~response,
colors = likert_colors,
text = ~paste0(round(percent, 1), "%"),
hoverinfo = 'text',
orientation = 'h') %>%
layout(
barmode = 'stack',
title = list(text = "Preferred Education Delivery Formats", x = 0.5, font = list(size = 20)),
annotations = list(
list(
x = 0.5,
y = 1.1,
text = "<i>Q. Preferred formats for education and capacity-building initiatives:</i>",
xref = "paper",
yref = "paper",
xanchor = "center",
showarrow = FALSE,
font = list(size = 14, color = "gray")
)
),
xaxis = list(title = "Percentage of Respondents", range = c(0, 100), ticksuffix = "%"),
yaxis = list(title = "", automargin = TRUE),
legend = list(title = list(text = "Agreement Level")),
margin = list(l = 180, r = 40, b = 60, t = 100) # increased top margin for subtitle
)
edu_format_other_themes <- tibble::tibble(
Theme = c(
"Asynchronous Access / Flexibility",
"General Online Learning Preference"
),
Quote = c(
"Recorded seminars to allow for flexibility with viewing.",
"Online."
)
)
edu_format_other_themes %>%
kbl(caption = "Other Suggested Education Delivery Formats (Q13b)") %>%
kable_styling(
full_width = FALSE,
bootstrap_options = c("hover", "condensed", "striped"),
position = "center"
) %>%
column_spec(1, bold = TRUE, width = "35%") %>%
column_spec(2, width = "65%")
| Theme | Quote |
|---|---|
| Asynchronous Access / Flexibility | Recorded seminars to allow for flexibility with viewing. |
| General Online Learning Preference | Online. |
Respondents shared common challenges they face in accessing education opportunities. These ranged from time constraints and cost to geographic isolation and lack of access to appropriate resources. The chart and quotes below illustrate key themes.
barriers_clean <- NEEDS_Education %>%
select(nas_barriers) %>%
filter(!is.na(nas_barriers),
!str_to_lower(nas_barriers) %in% c("na", "n/a", "none", "nil", "no", "nah", "")) %>%
mutate(nas_barriers = str_squish(str_to_lower(nas_barriers)))
barrier_quotes <- tibble::tibble(
Theme = c(
"Geography / Travel",
"Advanced / Non-Intro Content",
"Time Constraints",
"Language / Comprehension",
"Time Constraints & Cost",
"Time Constraints",
"Multiple Barriers (Time, Cost, Culture)",
"Access in Rural Areas",
"Geography / Travel",
"Time Constraints",
"Time Constraints",
"Time Constraints",
"Time Constraints",
"Time Constraints",
"Time Constraints",
"Time Constraints"
),
Quote = c(
"Geographical area.",
"Needing training that is advanced, not introductory. Also time.",
"Lack of time.",
"Language / understanding.",
"Time constraints. Cost should be zero.",
"Time management.",
"Finance, access to education, cultural competence, flexibility, time constraint.",
"Lack of access in rural areas. Diverse learner needs. Time barrier.",
"Travel might be a barrier if outside Ontario.",
"Time.",
"Working full-time and taking classes.",
"Scheduling during office hours.",
"Limitations on continuing education time.",
"Workload acuity. Patient care comes first.",
"Time constraints.",
"Time."
)
)
theme_counts <- barrier_quotes %>%
mutate(Theme = case_when(
str_detect(Theme, "Time") ~ "Time Constraints",
str_detect(Theme, "Geography") ~ "Geography / Travel",
str_detect(Theme, "Access|Advanced") ~ "Access / Level of Education",
str_detect(Theme, "Cost|Finance") ~ "Cost / Financial",
str_detect(Theme, "Language") ~ "Language / Comprehension",
TRUE ~ Theme
)) %>%
count(Theme)
plot_ly(theme_counts,
x = ~n,
y = ~reorder(Theme, n),
type = 'bar',
orientation = 'h',
textposition = 'auto',
marker = list(color = RColorBrewer::brewer.pal(n = nrow(theme_counts), name = "Set3")),
hoverinfo = 'text') %>%
layout(
title = list(text = "Reported Barriers to Education/Training", x = 0.5, font = list(size = 20)),
annotations = list(
list(
x = 0.35,
y = 1.12,
text = "<i>Q. Please share any challenges or barriers you would anticipate <br> in accessing additional educational/training resources</i>",
xref = "paper",
yref = "paper",
xanchor = "center",
showarrow = FALSE,
font = list(size = 14, color = "gray")
)
),
xaxis = list(title = "Number of Respondents", tickfont = list(size = 14)),
yaxis = list(title = "", tickfont = list(size = 14), automargin = TRUE),
margin = list(l = 180, r = 40, b = 60, t = 100),
showlegend = FALSE
)
Several participants offered free-text comments on broader system-level challenges and potential solutions. These comments were grouped by theme and include concerns around access, funding, family involvement, and system navigation.
| Theme | Quote |
|---|---|
| Access & System Navigation | Increased access to counselling in an ongoing way… there is an agency that purports to support children, but only offers single sessions… differential referrals to psychiatry sources… increasing education in schools… more youth community groups…….Early access and fast access to specialist care, to review case in the moment…. crisis prevention |
| Family & Community Involvement | Parents should also help us in talking and caring for the child and youth, so as to make our work easier. |
| Specialist Availability | Frustrated that many specialties have initiatives to upgrade primary care instead of improving availability of specialist consults. Psychiatry and rheumatology are major bottlenecks. |
| Specialist Availability | Psychiatrists who will actually see patients and follow-up — CAMH rejects most referrals and the ones that go through are not very helpful. |
| Family & Community Involvement | Involving not just medical practitioners but also the community and parents — their suggestions matter. |
| Funding | We need OHIP-funded psychotherapy to be ubiquitously available. Public health outreach to youth. Parenting training for children with complex needs…..the more funding and resources available the better |
| Public Education | More providers available in schools/communities that are OHIP-funded. |