The PHQ-9 is a “Self-administered 9-item instrument based on the nine DSM-V criteria listed under criterion A for Major Depressive Disorder. The instrument aids in guiding criteria based diagnosis of depressive symptoms, can assist in identifying treatment goals, determining severity of symptoms, as well as guiding clinical intervention (VA.gov).”
The PHQ-9 was evaluated as a patient-reported outcome measures in veterans by Katz et. al. (2021). They found that “the PHQ-9 functions more as a general measure of symptoms or distress than as a disease-specific scale. This supports its use as a PROM for patients beyond those with major depression, including those with related diagnoses and those with comorbidities, and use of related PROM-PMs in clinical settings where diagnoses may not be precise and comorbidities may be common.”
Recommendations for depression severity and questions associated with the scale can be found at: https://med.stanford.edu/fastlab/research/imapp/msrs/_jcr_content/main/accordion/accordion_content3/download_256324296/file.res/PHQ9%20id%20date%2008.03.pdf
Severity | Score |
---|---|
Minimal Depression | 0-4 |
Mild Depression | 5-9 |
Moderate Depression | 10-14 |
Moderately Severe Depression | 15-19 |
Severe Depression | 20-27 |
head(phq9)
#Keep only identifier columns and the PHQ-9 total score columns
phq9.change=subset(phq9, select = c(1,2,3,14))
library(tidyr)
#Change from long to wide format
phq9.change=spread(phq9.change, key = `Event Name`, value = `PHQ9.Total`)
#Sanity check: If this comes back as false, need to go back to excel sheet and correct record ID where Case ID is name for some and numeric for others
n_occur <- data.frame(table(phq9.change$`Record ID`))
n_occur[n_occur$Freq > 1,]
#Reorder columns to match order of assessments
phq9.change <- phq9.change[, c(1,2,3, 5, 4)]
library('tidyverse')
#Calculate change in score between initial and discharge
phq9.change$change=phq9.change$`Individual Discharge`-phq9.change$`Individual Baseline`
#Calculate change in score between initial and reauthorization
phq9.change$change.reauth=phq9.change$`Individual Reauthorization`-phq9.change$`Individual Baseline`
#IF discharge value is available, use it to calculate change. If not, use the reevaluation value to calculate change
#Remove columns used to calculate to only leave column with change value
phq9.change= phq9.change %>%
mutate(change = coalesce(change,change.reauth))
phq9.change=subset(phq9.change, select = c(1:6))
phq9.change$improvement=phq9.change$change
phq9.change$improvement[phq9.change$improvement >= 0] <- "FALSE"
phq9.change$improvement[phq9.change$improvement < 0] <- "TRUE"
mean_baseline=mean(phq9.change$`Individual Baseline`, na.rm=T)
mean_reauth=mean(phq9.change$`Individual Reauthorization`, na.rm = T)
mean_discharge=mean(phq9.change$`Individual Discharge`, na.rm = T)
This table shows the total sample size available at each timepoint (N) and summary statistics for the PHQ9 scores during Baseline Evaluation, Reathurization, and Discharge. Additionally, it shows the summary statistics for score changes between baseline and discharge, or reauthorization when discharge has not occurred. The breakdown of “improvement” shows the number of individuals whos PHQ9 score did and did not improve during that time.
library(vtable)
phq9.change$`Record ID`=as.character(phq9.change$`Record ID`)
#Print table statistics in R Markdown
sumtable(phq9.change, vars = c('Individual Baseline','Individual Reauthorization', 'Individual Discharge', 'change', 'improvement'))
Variable | N | Mean | Std. Dev. | Min | Pctl. 25 | Pctl. 75 | Max |
---|---|---|---|---|---|---|---|
Individual Baseline | 229 | 17.183 | 6.048 | 1 | 12 | 22 | 27 |
Individual Reauthorization | 39 | 15.103 | 7.214 | 0 | 11 | 21.5 | 27 |
Individual Discharge | 21 | 14.667 | 5.598 | 4 | 10 | 18 | 26 |
change | 45 | -2.133 | 8.554 | -23 | -7 | 4 | 18 |
improvement | 45 | ||||||
… FALSE | 18 | 40% | |||||
… TRUE | 27 | 60% |
Change in Severity Score: When available, this frequency chart shows the distribution of score changes from baseline to discharge. When a discharge score is not yet available, it is the change from baseline to reauthorization.
### Histogram showing change in scores over time.
ggplot(phq9.change, aes(change)) +
geom_histogram(binwidth=5, color="black", fill= "grey") +
xlab("Change in Depression Score") +
ggtitle("Change in Severity Score")
Distribution of PHQ9 scores at each timepoint (Baseline, Reauthorization, and Discharge). Color coded dotted lines indicate mean for each group, while shaded regions show density of occurance. Depression scores of minimal to severe are indicated on chart.
### Distribution of scores
den.1=ggplot() +
geom_density(aes(`Individual Baseline`, fill="Baseline"), alpha=0.2, data=phq9.change) +
geom_density(aes(`Individual Reauthorization`, fill="Reauthorization"), alpha=0.2, data=phq9.change) +
geom_density(aes(`Individual Discharge`, fill="Discharge"), alpha=0.2, data=phq9.change) +
labs(title="PHQ-9",
subtitle="Distribution of Depression Scores",
x="Score") +
geom_vline(xintercept=mean_baseline, size=1, color="pink", linetype="dotted") +
geom_vline(xintercept=mean_reauth, size=1, color="blue", linetype="dotted") +
geom_vline(xintercept=mean_discharge, size=1, color="green", linetype="dotted") +
geom_vline(xintercept=4.1, size=0.5, color="black", linetype="dotted") +
geom_vline(xintercept=9.1, size=0.5, color="black", linetype="dotted") +
geom_vline(xintercept=14.1, size=0.5, color="black", linetype="dotted") +
geom_vline(xintercept=19.1, size=0.5, color="black", linetype="dotted") +
annotate(geom="text", x=2, y=0.075, label="Minimal", color="black")+
annotate(geom="text", x=7, y=0.075, label="Mild", color="black")+
annotate(geom="text", x=12, y=0.075, label="Moderate", color="black")+
annotate(geom="text", x=17, y=0.075, label="Mod. Severe", color="black")+
annotate(geom="text", x=23, y=0.075, label="Severe", color="black") +
ylab("Density") +
labs(fill='Timepoint')
den.1
Flow of client scores between depression severity scores between Basleline and Discharge, or Reauthorization when Discharge scores are not yet available. The left hand coloumn shows the distribution of scores among severity categories at “Baseline”. Following the color coded sections to the “Current” column displays the proportion of clients at each starting baseline category vs their current severity rating.
#Create a column with disk level categories instead of numbers, then describe improvement based on categorical changes
phq9.change$risk.level.init=phq9.change$`Individual Baseline`
phq9.change$risk.level.init[phq9.change$risk.level.init > 19] <- "Severe"
phq9.change$risk.level.init[phq9.change$risk.level.init == 1] <- "Minimal"
phq9.change$risk.level.init[phq9.change$risk.level.init == 2] <- "Minimal"
phq9.change$risk.level.init[phq9.change$risk.level.init == 3] <- "Minimal"
phq9.change$risk.level.init[phq9.change$risk.level.init == 4] <- "Minimal"
phq9.change$risk.level.init[phq9.change$risk.level.init == 5] <- "Mild"
phq9.change$risk.level.init[phq9.change$risk.level.init == 6] <- "Mild"
phq9.change$risk.level.init[phq9.change$risk.level.init == 7] <- "Mild"
phq9.change$risk.level.init[phq9.change$risk.level.init == 8] <- "Mild"
phq9.change$risk.level.init[phq9.change$risk.level.init == 9] <- "Mild"
phq9.change$risk.level.init[phq9.change$risk.level.init == 10] <- "Moderate"
phq9.change$risk.level.init[phq9.change$risk.level.init == 11] <- "Moderate"
phq9.change$risk.level.init[phq9.change$risk.level.init == 12] <- "Moderate"
phq9.change$risk.level.init[phq9.change$risk.level.init == 13] <- "Moderate"
phq9.change$risk.level.init[phq9.change$risk.level.init == 14] <- "Moderate"
phq9.change$risk.level.init[phq9.change$risk.level.init == 15] <- "Moderately Severe"
phq9.change$risk.level.init[phq9.change$risk.level.init == 16] <- "Moderately Severe"
phq9.change$risk.level.init[phq9.change$risk.level.init == 17] <- "Moderately Severe"
phq9.change$risk.level.init[phq9.change$risk.level.init == 18] <- "Moderately Severe"
phq9.change$risk.level.init[phq9.change$risk.level.init == 19] <- "Moderately Severe"
phq9.change$risk.level.reauth=phq9.change$`Individual Reauthorization`
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth > 19] <- "Severe"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 1] <- "Minimal"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 2] <- "Minimal"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 3] <- "Minimal"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 4] <- "Minimal"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 5] <- "Mild"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 6] <- "Mild"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 7] <- "Mild"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 8] <- "Mild"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 9] <- "Mild"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 10] <- "Moderate"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 11] <- "Moderate"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 12] <- "Moderate"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 13] <- "Moderate"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 14] <- "Moderate"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 15] <- "Moderately Severe"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 16] <- "Moderately Severe"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 17] <- "Moderately Severe"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 18] <- "Moderately Severe"
phq9.change$risk.level.reauth[phq9.change$risk.level.reauth == 19] <- "Moderately Severe"
phq9.change$risk.level.discharge=phq9.change$`Individual Discharge`
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge > 19] <- "Severe"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 1] <- "Minimal"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 2] <- "Minimal"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 3] <- "Minimal"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 4] <- "Minimal"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 5] <- "Mild"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 6] <- "Mild"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 7] <- "Mild"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 8] <- "Mild"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 9] <- "Mild"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 10] <- "Moderate"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 11] <- "Moderate"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 12] <- "Moderate"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 13] <- "Moderate"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 14] <- "Moderate"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 15] <- "Moderately Severe"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 16] <- "Moderately Severe"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 17] <- "Moderately Severe"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 18] <- "Moderately Severe"
phq9.change$risk.level.discharge[phq9.change$risk.level.discharge == 19] <- "Moderately Severe"
#IF discharge value is available, use it to calculate change. If not, use the reevaluation value to calculate change
#Remove columns used to calculate to only leave column with change value
phq9.change$risk.level.change=phq9.change$risk.level.discharge
phq9.change= phq9.change %>%
mutate(risk.level.change = coalesce(risk.level.change,risk.level.reauth))
phq9.change <- phq9.change[, c(1:8,11)]
phq9.change$risk.level=paste(phq9.change$risk.level.init,phq9.change$risk.level.change,sep="-")
phq9.change$Discharged=phq9.change$`Individual Discharge`
phq9.change$Discharged[phq9.change$Discharged != "NA"] <- "TRUE"
### Summary of number of individuals with increasing and decreasing risk factors by discharge
phq9.risk.change=phq9.change
phq9.risk.change$risk.level.change[phq9.risk.change$risk.level.change == "Minimal" ] <- 1
phq9.risk.change$risk.level.change[phq9.risk.change$risk.level.change == "Mild"] <- 2
phq9.risk.change$risk.level.change[phq9.risk.change$risk.level.change == "Moderate"] <- 3
phq9.risk.change$risk.level.change[phq9.risk.change$risk.level.change == "Moderately Severe"] <- 4
phq9.risk.change$risk.level.change[phq9.risk.change$risk.level.change == "Severe"] <- 5
phq9.risk.change$risk.level.init[phq9.risk.change$risk.level.init == "Minimal" ] <- 1
phq9.risk.change$risk.level.init[phq9.risk.change$risk.level.init == "Mild"] <- 2
phq9.risk.change$risk.level.init[phq9.risk.change$risk.level.init == "Moderate"] <- 3
phq9.risk.change$risk.level.init[phq9.risk.change$risk.level.init == "Moderately Severe"] <- 4
phq9.risk.change$risk.level.init[phq9.risk.change$risk.level.init == "Severe"] <- 5
phq9.risk.change$risk.level.change=as.numeric(phq9.risk.change$risk.level.change)
phq9.risk.change$risk.level.init=as.numeric(phq9.risk.change$risk.level.init)
### Distribution of Severity Baseline to Current
##This needs work to add the appropriate stratum labels for each side
phq9.freq=phq9.change
phq9.freq=phq9.freq %>% drop_na(risk.level.change)
mockup_freq <- phq9.freq %>%
dplyr::count(risk.level.init, risk.level.change) %>%
mutate(proptot = prop.table(n))
mockup_freq <- na.omit(mockup_freq)
mockup_freq$risk.level.init <- factor(mockup_freq$risk.level.init, levels=c('Minimal', 'Mild', 'Moderate', 'Moderately Severe', 'Severe'))
levels(mockup_freq$risk.level.init)
#eventually remove rows with NA here
library(dataMaid)
library(lubridate)
library(summarytools)
library(ggstatsplot)
library(gridExtra)
library(Rmisc)
library(ggfortify)
library(ggpubr)
library(factoextra)
library(ggpubr)
library(forcats)
library(RColorBrewer)
library(ggrepel)
library(ggalluvial)
ggplot(as.data.frame(mockup_freq),
aes(y = proptot, axis1 = risk.level.init, axis2 = risk.level.change)) +
geom_alluvium(aes(fill = risk.level.init), width = 1/12) +
geom_stratum(width = 1/12 , colour = "darkgrey") +
geom_label(stat = "stratum", infer.label = TRUE, fill="white", fontface="bold", colour="darkgrey", size=2) +
scale_x_discrete(limits = c("risk.level.init", "risk.level.change"),
expand = c(.1, .1),
labels = c("Baseline", "Current")) +
ggtitle("Flow of Severity between Baseline and Current Assessment") +
scale_fill_manual(values=c("grey", "yellow", "orange", "orangered", "darkred"),
name="Title",
breaks=c("Minimal", "Mild", "Moderate", "Moderately Severe","Severe"),
labels=c("Minimal", "Mild", "Moderate", "Moderately Severe.","Severe")) +
theme_minimal() +
theme(legend.position = "right",
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()) +
labs(y = "Proportion of total")
library(DT)
phq9.datatable= phq9.change[, c(1:7,10:11)]
datatable(data = phq9.datatable, width=NULL, filter = "top", caption= "PHQ-9 Summary Results", rownames=F, colnames = c('Record ID', 'Case ID', 'Baseline Score', 'Reauthorization Score', 'Discharge Score', 'Change in Score', "Improvement (T/F)", "Risk Level Initial:Current", "Discharged (T/F)"),
options = list(pagelength=25,
initComplete = JS(
"function(settings, json) {",
"$(this.api().table().header()).css({'background-color': 'grey', 'color': '#fff'});",
"}")))
Evidence for the PCL for DSM-IV suggested 5 point decrease as a minimum threshold for determining whether an individual has responded to treatment and 10 point decrease as a minimum threshold for determining whether the improvement is clinically meaningful. Change scores for PCL-5 are currently being determined. It is expected that reliable and clinically meaningful change will be in a similar range. We recommend following the DSM-IV recommendations until new information is available.
https://www.ptsd.va.gov/professional/assessment/adult-sr/ptsd-checklist.asp
The PCL-5 can be scored in different ways: A total symptom severity score (range - 0-80) can be obtained by summing the scores for each of the 20 items. DSM-5 symptom cluster severity scores can be obtained by summing the scores for the items within a given cluster, i.e., cluster B (Re-experiencing; items 1-5), cluster C (Avoidance; items 6-7), cluster D (Negative alternations in cognition and mood; items 8-14), and cluster E (Hyper-arousal; items 15-20). A provisional PTSD diagnosis can be made by treating each item rated as 2 = “Moderately” or higher as a symptom endorsed, then following the DSM-5 diagnostic rule which requires at least: 1 B item (questions 1-5), 1 C item (questions 6-7), 2 D items (questions 8-14), 2 E items (questions 15-20).
Initial research suggests that a PCL-5 cutoff score between 31-33 is indicative of probable PTSD across samples. However, additional research is needed. Further, because the population and the purpose of the screening may warrant different cutoff scores, users are encouraged to consider both of these factors when choosing a cutoff score.
Cohen, J., et al. (2015). Preliminary Evaluation of the Psychometric Properties of the PTSD Checklist for DSM – 5. (Conference Presentation). doi: 10.12140/2.1.4448.5444
pcl5 <- data.frame(lapply(pcl5, function(x) {
gsub("Not at All", "0", x)
}))
pcl5 <- data.frame(lapply(pcl5, function(x) {
gsub("A Little Bit", "1", x)
}))
pcl5 <- data.frame(lapply(pcl5, function(x) {
gsub("Moderately", "2", x)
}))
pcl5 <- data.frame(lapply(pcl5, function(x) {
gsub("Quite a Bit", "3", x)
}))
pcl5 <- data.frame(lapply(pcl5, function(x) {
gsub("Extremely", "4", x)
}))
pcl5 <- pcl5 %>%
mutate_at(c(5:24), as.numeric)
pcl5$clusterA <- as.numeric(apply(pcl5[,5:9], 1, sum))
pcl5$clusterB <- as.numeric(apply(pcl5[,10:11], 1, sum))
pcl5$clusterC <- as.numeric(apply(pcl5[,12:18], 1, sum))
pcl5$clusterD <- as.numeric(apply(pcl5[,19:24], 1, sum))
#Keep only identifier columns and the total score columns
pcl5.tot=subset(pcl5, select = c(1,2,3,25))
pcl5.tot=spread(pcl5.tot, key = `Event.Name`, value = `PCL5.Total`)
pcl5.tot <- pcl5.tot[, c(1,2,3, 5, 4)]
pcl5.clusA=subset(pcl5, select = c(1,2,3,27))
pcl5.clusA=spread(pcl5.clusA, key = `Event.Name`, value = `clusterA`)
pcl5.clusA <- pcl5.clusA[, c(1,2,3, 5, 4)]
pcl5.clusB=subset(pcl5, select = c(1,2,3,28))
pcl5.clusB=spread(pcl5.clusB, key = `Event.Name`, value = `clusterB`)
pcl5.clusB <- pcl5.clusB[, c(1,2,3, 5, 4)]
pcl5.clusC=subset(pcl5, select = c(1,2,3,29))
pcl5.clusC=spread(pcl5.clusC, key = `Event.Name`, value = `clusterC`)
pcl5.clusC <- pcl5.clusC[, c(1,2,3, 5, 4)]
pcl5.clusD=subset(pcl5, select = c(1,2,3,30))
pcl5.clusD=spread(pcl5.clusD, key = `Event.Name`, value = `clusterD`)
pcl5.clusD <- pcl5.clusD[, c(1,2,3, 5, 4)]
pcl5.tot$`Individual Baseline`=as.numeric(pcl5.tot$`Individual Baseline`)
pcl5.tot$`Individual Reauthorization`=as.numeric(pcl5.tot$`Individual Reauthorization`)
pcl5.tot$`Individual Discharge`=as.numeric(pcl5.tot$`Individual Discharge`)
#Calculate change in score between initial and discharge
pcl5.tot$change=pcl5.tot$`Individual Discharge`-pcl5.tot$`Individual Baseline`
#Calculate change in score between initial and reauthorization
pcl5.tot$change.reauth=pcl5.tot$`Individual Reauthorization`-pcl5.tot$`Individual Baseline`
#IF discharge value is available, use it to calculate change. If not, use the reevaluation value to calculate change
#Remove columns used to calculate to only leave column with change value
pcl5.tot= pcl5.tot %>%
mutate(change = coalesce(change,change.reauth))
pcl5.tot=subset(pcl5.tot, select = c(1:6))
Table including the sample size (N) and summary statistics for PCL-5 scores. “Change” varaible is the difference between the baseline and discharge score, or baseline and reauthorization score when no discharge score is available.
Table also includes “Improvement”, which categorizes changes in scores into those described by the VA for clinical improvement, responding to treatment, no response, or increased PTSD symptoms.
library(vtable)
sumtable(pcl5.tot)
Variable | N | Mean | Std. Dev. | Min | Pctl. 25 | Pctl. 75 | Max |
---|---|---|---|---|---|---|---|
Individual Baseline | 222 | 50.577 | 17.356 | 4 | 40 | 64 | 80 |
Individual Reauthorization | 38 | 44.868 | 19.837 | 1 | 36.25 | 56.75 | 76 |
Individual Discharge | 20 | 46.55 | 18.389 | 11 | 34.5 | 57.5 | 80 |
change | 44 | -7.25 | 20.356 | -69 | -16.5 | 5 | 23 |
Change in PTSD Severity: Graph shows frequency of score changes between baseline and discharge assessments, or baseline and reauthorization assessments when discharge data is not available. Vertical lines seperate changes in scores into meaninful categories of “Responding to Treatment” (>5 point decrease), Clinical improvement” (>10 point decrease), or “Increased PTSD Symptoms”.
ggplot(pcl5.tot, aes(change)) +
geom_histogram(binwidth=1, color="black", fill= "grey") +
xlab("Change in PTSD Score") +
ggtitle("Change in Severity Score") +
geom_vline(xintercept=-10, size=1, color="grey", linetype="dotted") +
annotate(geom="text", x=-20, y=5.5, size=2, label="Clinical Improvement", color="black") +
geom_vline(xintercept=-4, size=1, color="grey", linetype="dotted") +
annotate(geom="text", x=-6.5, y=5.5, size=2, label="Responding", color="black") +
annotate(geom="text", x=-6.5, y=5.35, size=2, label="to", color="black") +
annotate(geom="text", x=-6.5, y=5.2, size=2, label="Treatment", color="black") +
geom_vline(xintercept=-1, size=1, color="grey", linetype="dotted") +
annotate(geom="text", x=16.5, y=5.5, size=2, label="Increased PTSD Symptoms", color="black")
Proportion of Clinets reporting clinically improved PTSD symptoms, response to treatment, no response to treatment, or increased PTSD symptoms. The graph on the left includes all changes in scores between baseline and discharge, and using reathorization scores when discharge scores are not available. The chart on the right includes only individuals who have completed the discharge assessment. Sample sizes for each category and indicated within pie wedges.
library(gridExtra)
library(ggpubr)
### Table summary of change in score.
pcl5.tot$improvement=pcl5.tot$change
pcl5.tot$improvement[pcl5.tot$improvement < -9] <- "Clinical Improvement"
pcl5.tot$improvement[pcl5.tot$improvement == -5] <- "Responding to Treatment"
pcl5.tot$improvement[pcl5.tot$improvement == -6] <- "Responding to Treatment"
pcl5.tot$improvement[pcl5.tot$improvement == -7] <- "Responding to Treatment"
pcl5.tot$improvement[pcl5.tot$improvement == -8] <- "Responding to Treatment"
pcl5.tot$improvement[pcl5.tot$improvement == -9] <- "Responding to Treatment"
pcl5.tot$improvement[pcl5.tot$improvement >0 & pcl5.tot$improvement <= 80] <- "Increased PTSD Symptoms" # Replace values in range
pcl5.tot$improvement[pcl5.tot$improvement == -4] <- "No Response"
pcl5.tot$improvement[pcl5.tot$improvement == -3] <- "No Response"
pcl5.tot$improvement[pcl5.tot$improvement == -2] <- "No Response"
pcl5.tot$improvement[pcl5.tot$improvement == -1] <- "No Response"
pcl5.tot$improvement[pcl5.tot$improvement == -0] <- "No Response"
pcl5.tot1=pcl5.tot %>% drop_na(`improvement`)
pcl5.tot1$improvement <- factor(pcl5.tot1$improvement, levels = c("Clinical Improvement", "Responding to Treatment", "No Response", "Increased PTSD Symptoms"))
tab1=as.data.frame(table(pcl5.tot1$improvement))
tab1$perc=tab1$Freq/nrow(pcl5.tot1)
tab1.p=ggplot(tab1, aes(x="", y=perc, fill=Var1)) +
geom_bar(stat="identity", width=1) +
coord_polar("y", start=0) +
xlab("") +
ggtitle("All Reauth & Discharges") +
geom_text(aes(label = Freq),
position = position_stack(vjust = 0.5)) +
ylab("Proportion")
pcl5.tot2=pcl5.tot %>% drop_na(`Individual Discharge`)
pcl5.tot2$improvement <- factor(pcl5.tot2$improvement, levels = c("Clinical Improvement", "Responding to Treatment", "No Response", "Increased PTSD Symptoms"))
tab2=as.data.frame(table(pcl5.tot2$improvement))
tab2$perc=tab2$Freq/nrow(pcl5.tot2)
tab2.p=ggplot(tab2, aes(x="", y=perc, fill=Var1)) +
geom_bar(stat="identity", width=1) +
coord_polar("y", start=0) +
xlab("") +
ggtitle("Discharged Only") +
geom_text(aes(label = Freq),
position = position_stack(vjust = 0.5)) +
ylab("Proportion")
ggarrange(tab1.p , tab2.p,
ncol=2, nrow=1, common.legend = TRUE, legend="bottom")
Distribution of PCL-5 scores at each timepoint (Baseline, Reauthorization, and Discharge). Color coded dotted lines indicate mean for each group, while shaded regions show density of occurance. The shaded region indicates field accepted scores indicating “probable PTSD”.
### Distribution of scores
mean_baseline2=mean(pcl5.tot$`Individual Baseline`, na.rm=T)
mean_reauth2=mean(pcl5.tot$`Individual Reauthorization`, na.rm = T)
mean_discharge2=mean(pcl5.tot$`Individual Discharge`, na.rm = T)
den.2=ggplot() +
geom_density(aes(`Individual Baseline`, fill="Baseline"), alpha=0.2, data=pcl5.tot) +
geom_density(aes(`Individual Reauthorization`, fill="Reauthorization"), alpha=0.2, data=pcl5.tot) +
geom_density(aes(`Individual Discharge`, fill="Discharge"), alpha=0.2, data=pcl5.tot) +
labs(title="PCL-5",
subtitle="Distribution of PTSD Scores",
x="Score") +
ylab("Density") +
annotate('rect', xmin=31, xmax=33, ymin=0, ymax=Inf, alpha=.2, fill='black') +
geom_vline(xintercept=mean_baseline2, size=1, color="pink", linetype="dotted") +
geom_vline(xintercept=mean_reauth2, size=1, color="blue", linetype="dotted") +
geom_vline(xintercept=mean_discharge2, size=1, color="green", linetype="dotted") +
labs(fill='Timepoint')
den.2
library(DT)
pcl5.datatable= pcl5.tot
datatable(data = pcl5.datatable, width=NULL, filter = "top", caption= "PHQ-9 Summary Results", rownames=F, colnames = c('Record ID', 'Case ID', 'Baseline Score', 'Reauthorization Score', 'Discharge Score', 'Change in Score', "Improvement Type"),
options = list(pagelength=25,
initComplete = JS(
"function(settings, json) {",
"$(this.api().table().header()).css({'background-color': 'grey', 'color': '#fff'});",
"}")))
The Connor-Davidson Resillience Scale
Measure of psychological resillience. These ratings result in a number between 0–40, and higher scores indicate higher resilience. The 10 item version comprises items 1, 4, 6, 7, 8, 11, 14, 16, 17, 19 from the original scale, and was developed by Drs. Campbell-Sills and Stein, at the University of California, San Diego, on the basis of factor analysis. In a community survey of 764 US adults, a mean score of 31.8 (SD = 5.4) was obtained for the CD-RISC 10 (Campbell-Sills L, Forde DR, Stein MB. J Psychiatric Research (2009), doi:10.1016/j.jpsychires.2009.01.013). The population quartile scores for the CD-RISC-10 are as follows: 25th % = 29; 50th % = 32; 75th % = 36. An almost identical mean score was obtained by Davidson in the US general population sample studied in the 2003 report above.
Wingo et al (2017) found mean of 23.6 (7.9 SD) in veterans with PTSD and depression
cd.risc[cd.risc == "Not at all"] <- "0"
cd.risc[cd.risc == "Rarely True"] <- "1"
cd.risc[cd.risc == "Sometimes True"] <- "2"
cd.risc[cd.risc == "Often True"] <- "3"
cd.risc[cd.risc == "True Nearly all of the Time"] <- "4"
cd.risc <- cd.risc %>%
mutate_at(c(5:14), as.numeric)
cd.risc$total <- as.numeric(apply(cd.risc[,5:14], 1, sum))
cd.risc.tot=subset(cd.risc, select = c(1,2,3,16))
cd.risc.tot=spread(cd.risc.tot, key = `Event Name`, value = total)
cd.risc.tot$`Individual Baseline`=as.numeric(cd.risc.tot$`Individual Baseline`)
cd.risc.tot$`Individual Reauthorization`=as.numeric(cd.risc.tot$`Individual Reauthorization`)
cd.risc.tot$`Individual Discharge`=as.numeric(cd.risc.tot$`Individual Discharge`)
#Calculate change in score between initial and discharge
cd.risc.tot$change=cd.risc.tot$`Individual Discharge`-cd.risc.tot$`Individual Baseline`
#Calculate change in score between initial and reauthorization
cd.risc.tot$change.reauth=cd.risc.tot$`Individual Reauthorization`-cd.risc.tot$`Individual Baseline`
#IF discharge value is available, use it to calculate change. If not, use the reevaluation value to calculate change
#Remove columns used to calculate to only leave column with change value
cd.risc.tot= cd.risc.tot %>%
mutate(change = coalesce(change,change.reauth))
cd.risc.tot=subset(cd.risc.tot, select = c(1:6))
This table shows the total sample size available at each timepoint (N) and summary statistics for the CD-RISC scores during Baseline Evaluation, Reathurization, and Discharge.
cd.risc.tot$`Record ID`=as.character(cd.risc.tot$`Record ID`)
sumtable(cd.risc.tot)
Variable | N | Mean | Std. Dev. | Min | Pctl. 25 | Pctl. 75 | Max |
---|---|---|---|---|---|---|---|
Case ID | 216 | 23911.681 | 2887.611 | 2310 | 22815.25 | 25374.5 | 29069 |
Individual Baseline | 214 | 21.005 | 7.286 | 1 | 17 | 25.75 | 40 |
Individual Reauthorization | 37 | 22.703 | 9.792 | 4 | 16 | 31 | 40 |
Individual Discharge | 18 | 19.444 | 7.965 | 8 | 13.25 | 23.75 | 35 |
change | 40 | 1.55 | 7.507 | -10 | -3 | 5 | 27 |
Change in Severity Score: When available, this frequency chart shows the distribution of score changes from baseline to discharge. When a discharge score is not yet available, it is the change from baseline to reauthorization.
ggplot(cd.risc.tot, aes(change)) +
geom_histogram(binwidth=5, color="black", fill= "grey") +
xlab("Change in Resiliency Score") +
ggtitle("Change in Severity Score")
Distribution of CD-RISC scores at each timepoint (Baseline, Reauthorization, and Discharge). Color coded dotted lines indicate mean for each group, while shaded regions show density of occurance. Depression scores of minimal to severe are indicated on chart. The dotted grey line indicates the average CD-RISC score previously found for veterans with PTSD and depression (Wingo et. al, 2017), and the shaded gray box indicates a SD of 7.9 for the same population.
Note: Mean scores for the general public are higher, and the quartiles are as follows: 25th % = 29; 50th % = 32; 75th % = 36.
mean_baseline3=mean(cd.risc.tot$`Individual Baseline`, na.rm = T)
mean_reauth3=mean(cd.risc.tot$`Individual Reauthorization`, na.rm = T)
mean_discharge3=mean(cd.risc.tot$`Individual Discharge`, na.rm = T)
#shaded grey box indicates previous findings of mean +/- SD for veterans with PTSD and Depression
den.3=ggplot() +
geom_density(aes(`Individual Baseline`, fill="Baseline"), alpha=0.2, data=cd.risc.tot) +
geom_density(aes(`Individual Reauthorization`, fill="Reauthorization"), alpha=0.2, data=cd.risc.tot) +
geom_density(aes(`Individual Discharge`, fill="Discharge"), alpha=0.2, data=cd.risc.tot) +
labs(title="CD-RISC",
subtitle="Distribution of Resiliency Scores",
x="Score") +
ylab("Density") +
annotate("rect", xmin=15.7, xmax=31.5, ymin=0, ymax=Inf, alpha = .1) +
geom_vline(xintercept=mean_baseline3, size=1, color="pink", linetype="dotted") +
geom_vline(xintercept=mean_reauth3, size=1, color="blue", linetype="dotted") +
geom_vline(xintercept=mean_discharge3, size=1, color="green", linetype="dotted") +
geom_vline(xintercept=23.6, size=1, color="grey", linetype="dotted") +
annotate(geom="text", x=26.5, y=0.075, size=3, label="Veterans with PTSD", color="black") +
annotate(geom="text", x=26.5, y=0.072, size=3, label="and Depression", color="black")+
annotate(geom="text", x=26.5, y=0.069, size=2, label="(Wingo et. al., 2017)", color="black") +
labs(fill='Timepoint')
den.3
library(DT)
cd.risc.datatable= cd.risc.tot
datatable(data = cd.risc.datatable, width=NULL, filter = "top", caption= "PHQ-9 Summary Results", rownames=F, colnames = c('Record ID', 'Case ID', 'Baseline Score', 'Reauthorization Score', 'Discharge Score', 'Change in Score'),
options = list(pagelength=25,
initComplete = JS(
"function(settings, json) {",
"$(this.api().table().header()).css({'background-color': 'grey', 'color': '#fff'});",
"}")))
Key Takeaways
Per Assessment Summary
Summary Table
Summary data is presented showing how cumulative improvement scores have changed over time. Please note that all data presented is analyzed through the month listed, not within that 30 day period (ex. May data includes all data prior to may, including April).
Changes displayed in negative values for the PHQ-9 and PCL-5 indicate improvement, while a positive value for the CD-Risc indicates improvement.
sumtab= data.frame(
Month = c("April", "May", "June", "July", "August"),
N.Anaylzed=c (37, 39, 40, 44, 45),
N.Discharged=c(10,16, 18, 21, 21),
PHQ9= c(-1.216, -0.769, -0.85, -1.82, -2.13),
PCL5=c(-2.833, -2.921, -3.154, -6.116, -7.25),
CDRisc=c(0.059,-0.086, -0.171, 1.385, 1.55)
)
sumtab$Month=
sumtab$Month <- factor(sumtab$Month, levels=c('April', 'May', 'June', 'July', 'August'))
datatable(data = sumtab, width=NULL, filter = "top", caption= "Cumulative Results by Month", rownames=F, colnames = c('Month', 'N Analysed', "N Discharged", 'Cumulative PHQ-9', 'Cumulative PCL-5', 'Cumulative CD-Risc'),
options = list(pagelength=25,
initComplete = JS(
"function(settings, json) {",
"$(this.api().table().header()).css({'background-color': 'grey', 'color': '#fff'});",
"}")))
Summary Graphics
Graphic depicting the change in improvement over time in percentages.
PHQ-9 and CD-Risc: Clinical improvment is indicated by a greater than 1 standard deviation improvment in scores for the baseline assessment.See “Per Assessment Summary” above for specific values.
PCL-5: Clinical improvement on a per-client basis is considered a minimum of 12.5% improvment in score. Responding to treatment is considered a minimum of 6.25% improvment.
sumtab.perc=sumtab
sumtab.perc$PHQ9.p=sumtab.perc$PHQ9/27*(-100)
sumtab.perc$PCL5.p=sumtab.perc$PCL5/80*(-100)
sumtab.perc$CDRisc.p=sumtab.perc$CDRisc/40*100
percents.long <- gather(sumtab.perc, Assessment, PercImprov, PHQ9.p:CDRisc.p, factor_key=TRUE)
facet_titles <- c(
`PHQ9.p` = "PHQ-9: Despression Scale",
`PCL5.p` = "PCL-5: PTSD Scale",
`CDRisc.p` = "CD-Risc: Resilience Scale"
)
perc.pl=ggplot(percents.long, aes(Month, PercImprov), group=Assessment) +
geom_line(aes(group=1), color="green") +
geom_point(color = "green") +
ylab("Percent Improvement") +
facet_wrap( ~ Assessment, ncol=1, scales = "free", labeller = as_labeller(facet_titles))
ggplotly(perc.pl, tooltip=c("Month", "Assessment", "PercImprov"))
#Graphic depicting the change in improvment over time in raw scores.
sumtab.long <- gather(sumtab, Assessment, Score, PHQ9:CDRisc, factor_key=TRUE)
facet_titles <- c(
`PHQ9` = "PHQ-9 (Improvment indicated by decrease)",
`PCL5` = "PCL-5 (Improvment indicated by decrease)",
`CDRisc` = "CD-Risc (Improvment indicated by increase)"
)
sum.pl1=ggplot(sumtab.long, aes(Month, Score), group=Assessment) +
geom_line(aes(group=1), color="grey") +
geom_point(color = "grey") +
facet_wrap( ~ Assessment, ncol=1, scales = "free", labeller = as_labeller(facet_titles))
ggplotly(sum.pl1)