Data Cleaning and Preparation- pre wide format 1. Recode Self harm variables to binary and then calculate a new combined binary variable of “any self harm yes/no” 2. Make Attendance variables and last session attended variables

### Code to create binary self-harm variables and presence variables without overwriting the originals ###
library(readxl)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyr)
library(readr)

NoDup_PurrbleAnon <- read_csv("Desktop/Purrbel/NoDup_PurrbleAnon.csv")
## Warning: One or more parsing issues, call `problems()` on your data frame for details,
## e.g.:
##   dat <- vroom(...)
##   problems(dat)
## Rows: 1941 Columns: 140
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (40): psid, randomization, so, gi, ethnicity, identity_group, startdate,...
## dbl (89): Week, age, source, status, progress, durationinseconds, finished, ...
## lgl (11): firstname, q45_3_text, q46_6_text, GAD7_Complete, PHQ9_Complete, S...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#View(NoDup_PurrbleAnon)

NoDup_PurrbleAnon <- NoDup_PurrbleAnon %>%
  mutate(
    # If missing, then NA. If <= 1 then 0, else 1
    SHQ1 = ifelse(is.na(shqscreener1), NA, ifelse(shqscreener1 <= 1, 0, 1)),
    SHQ2 = ifelse(is.na(shqscreener2), NA, ifelse(shqscreener2 <= 1, 0, 1)),
    SHQ3 = ifelse(is.na(shqscreener3), NA, ifelse(shqscreener3 <= 1, 0, 1))
  ) %>%
  mutate(
    # If any of SHQ1, SHQ2, or SHQ3 is missing, SHQ_Any is missing.
    # If all three are 0, SHQ_Any is 0, else 1.
    SHQ_Any = case_when(
      is.na(SHQ1) | is.na(SHQ2) | is.na(SHQ3) ~ NA_real_,
      SHQ1 == 0 & SHQ2 == 0 & SHQ3 == 0 ~ 0,
      TRUE ~ 1
    )
  )

Data Cleaning and preparation: 2. Transform from wide to long format 3. Calculate a new condition variable

Note: Do not get confused! In the datset for user ID, T means transgender and C means Cisgender- IT DOES NOT MEAN TREATMENT AND CONTROL. This is based on Seonaid’s original participant tracking database and aligns with all of that data!

Data Cleaning and Preparation: - Calculate pre-test (avg of weeks 1-3) and post-test (average of weeks 10-13) variables

library(readxl)
library(dplyr)
library(tidyr)
library(readr)

# Define the vector of outcomes for which we need pre/post lists
outcomes <- c("shqscreener1", "shqscreener2", "shqscreener3", 
              "DERS8_Sum", "GAD7_Sum", 
              "PHQ9_Sum", "SHS_Pathways", "SHS_Agency", "SHS_TotalHope",
              "ucla_Sum", "pmerq_Focus_Avg", "pmerq_Distract_Avg", "pmerq_AD_Avg")

# Create the pretest list (weeks 1-3 for each outcome)
pretest_list <- unlist(lapply(outcomes, function(x) paste0(x, "_", 1:3)))

# Create the posttest list (weeks 11-13 for each outcome)
posttest_list <- unlist(lapply(outcomes, function(x) paste0(x, "_", 11:13)))

for (outcome in outcomes) {
  # Identify the pre-test columns for this outcome
  pre_cols <- pretest_list[grepl(paste0("^", outcome, "_"), pretest_list)]
  
  # Identify the post-test columns for this outcome
  post_cols <- posttest_list[grepl(paste0("^", outcome, "_"), posttest_list)]
  
  # Create the names for the new Pre_ and Post_ columns
  pre_colname <- paste0("Pre_", outcome)
  post_colname <- paste0("Post_", outcome)
  
  # Calculate row means for pre-test columns (weeks 1-3)
  purrble_wide[[pre_colname]] <- rowMeans(purrble_wide[, pre_cols, drop = FALSE], na.rm = TRUE)
  
  # Calculate row means for post-test columns (weeks 11-13)
  purrble_wide[[post_colname]] <- rowMeans(purrble_wide[, post_cols, drop = FALSE], na.rm = TRUE)
}

#View(purrble_wide)

Data Cleaning and Preparation: - Calculate Attendance Variables for Each Week (for later survival curve analyses!) - Calculate “Week of Dropout” Variable

library(dplyr)

# Create a vector of weeks
weeks <- 1:13

# For each week, check if any of that week's columns are non-NA.
# We use `rowSums(!is.na(across(...))) > 0` to check for the presence of any data.
for (w in weeks) {
  purrble_wide <- purrble_wide %>%
    mutate(!!paste0("ATT", w) := if_else(
      rowSums(!is.na(across(ends_with(paste0("_", w))))) > 0,
      1,
      0
    ))
}

purrble_wide <- purrble_wide %>%
  rowwise() %>%
  mutate(Last_Session = {
    # Extract the attendance values for all weeks
    att_values <- c_across(starts_with("ATT"))
    
    # Check if there is any attendance
    if (all(att_values == 0 | is.na(att_values))) {
      # If no attendance, set Last_Session to NA
      NA_integer_
    } else {
      # If there is attendance, find the last (max) week attended
      max(which(att_values == 1))
    }
  }) %>%
  ungroup()
#View(purrble_wide)
#colnames(purrble_wide)

Reporting baseline descriptive statistics of the sample (characteristics as reported at screening amongst those who were randomized) by condition: identity_group, Age

Problem note for Jess: I need Jess to code the ethnicity data and sexuality data into something usable- need this for reporting before any sort of publication and for all descriptive tables. People were able to write anything they wanted under those variables, so I do not have the ability to engage with the dataset for those accurately.

library(dplyr)
library(psych)

# 1. Continuous variable (e.g., age) by condition
age_desc <- describeBy(purrble_wide$age, purrble_wide$condition, mat = TRUE)
age_desc <- age_desc %>%
  select(group1, n, mean, sd, min, max) %>%
  rename(
    Condition = group1,
    N = n,
    Mean = mean,
    SD = sd,
    Min = min,
    Max = max
  )

cat("**Age by Condition (Baseline)**\n")
## **Age by Condition (Baseline)**
print(age_desc)
##             Condition  N     Mean       SD Min Max
## X11  Waitlist Control 78 20.06410 2.456583  16  25
## X12 Purrble Treatment 76 20.40789 2.281389  16  25
cat("\n")
# T-test for age by condition
t_result <- t.test(age ~ condition, data = purrble_wide)
cat("T-test for Age by Condition:\n")
## T-test for Age by Condition:
print(t_result)
## 
##  Welch Two Sample t-test
## 
## data:  age by condition
## t = -0.9002, df = 151.65, p-value = 0.3694
## alternative hypothesis: true difference in means between group Waitlist Control and group Purrble Treatment is not equal to 0
## 95 percent confidence interval:
##  -1.098336  0.410752
## sample estimates:
##  mean in group Waitlist Control mean in group Purrble Treatment 
##                        20.06410                        20.40789
cat("\n")
# Effect size (Cohen's d) using psych
cohen <- cohen.d(purrble_wide$age, purrble_wide$condition)
cat("Cohen's d for Age by Condition:\n")
## Cohen's d for Age by Condition:
print(cohen)
## Call: cohen.d(x = purrble_wide$age, group = purrble_wide$condition)
## Cohen d statistic of difference between two means
##      lower effect upper
## [1,] -0.17   0.15  0.46
## 
## Multivariate (Mahalanobis) distance between groups
## [1] 0.15
## r equivalent of difference between two means
## data 
## 0.07
cat("\n")
# Categorical Variable (identity_group) by condition
cat("Frequency of 'identity_group' by Condition (Baseline):\n")
## Frequency of 'identity_group' by Condition (Baseline):
print(table(purrble_wide$identity_group, purrble_wide$condition))
##      
##       Waitlist Control Purrble Treatment
##   c                  0                 1
##   C                 38                38
##   TGD               40                37
cat("\n")

Attrition Analysis by Condition Attrition is defined as dropping out of study prior to Week 11. (In other words, someone could have participated in any data collection during weeks 11-13 and count as enrolled).

Result: No difference in attrition by group

# Create an attrition variable: 1 if last session <= 10, else 0
purrble_wide$attrition <- ifelse(purrble_wide$Last_Session <= 10, 1, 0)

# Identify condition levels
cond_levels <- unique(purrble_wide$condition)
cond_levels <- cond_levels[!is.na(cond_levels)]
if (length(cond_levels) != 2) {
  stop("This code expects exactly two conditions for the comparison.")
}

# Extract data by condition
cond1_data <- purrble_wide[purrble_wide$condition == cond_levels[1], "attrition", drop = TRUE]
cond2_data <- purrble_wide[purrble_wide$condition == cond_levels[2], "attrition", drop = TRUE]

# Calculate descriptive statistics
cond1_n <- sum(!is.na(cond1_data))
cond1_mean <- mean(cond1_data, na.rm = TRUE)
cond1_sd <- sd(cond1_data, na.rm = TRUE)

cond2_n <- sum(!is.na(cond2_data))
cond2_mean <- mean(cond2_data, na.rm = TRUE)
cond2_sd <- sd(cond2_data, na.rm = TRUE)

# T-test comparing attrition by condition
tt <- t.test(attrition ~ condition, data = purrble_wide)

# Print results
cat("Attrition Analysis by Condition (prior to Week 11):\n\n")
## Attrition Analysis by Condition (prior to Week 11):
cat("Means and SD by Condition:\n")
## Means and SD by Condition:
cat(cond_levels[1], ": N =", cond1_n, "Mean =", round(cond1_mean, 3), "SD =", round(cond1_sd, 3), "\n")
## 1 : N = 78 Mean = 0.064 SD = 0.247
cat(cond_levels[2], ": N =", cond2_n, "Mean =", round(cond2_mean, 3), "SD =", round(cond2_sd, 3), "\n\n")
## 2 : N = 76 Mean = 0.092 SD = 0.291
cat("T-test results:\n")
## T-test results:
print(tt)
## 
##  Welch Two Sample t-test
## 
## data:  attrition by condition
## t = -0.64343, df = 146.68, p-value = 0.521
## alternative hypothesis: true difference in means between group Waitlist Control and group Purrble Treatment is not equal to 0
## 95 percent confidence interval:
##  -0.11401229  0.05800689
## sample estimates:
##  mean in group Waitlist Control mean in group Purrble Treatment 
##                      0.06410256                      0.09210526

Baseline Descriptive Analyses T-test to check for baseline differences in outcomes of interest by study condition Result: No difference in baseline pre-test measures

library(dplyr)
library(psych)

# Create vectors of pre- and post-test variables
pre_vars <- c("Pre_shqscreener1", "Pre_shqscreener2", "Pre_shqscreener3",
              "Pre_DERS8_Sum", "Pre_GAD7_Sum", "Pre_PHQ9_Sum",
              "Pre_SHS_Pathways", "Pre_SHS_Agency", "Pre_SHS_TotalHope",
              "Pre_ucla_Sum", "Pre_pmerq_Focus_Avg", "Pre_pmerq_Distract_Avg", "Pre_pmerq_AD_Avg")

post_vars <- c("Post_shqscreener1", "Post_shqscreener2", "Post_shqscreener3",
               "Post_DERS8_Sum", "Post_GAD7_Sum", "Post_PHQ9_Sum",
               "Post_SHS_Pathways", "Post_SHS_Agency", "Post_SHS_TotalHope",
               "Post_ucla_Sum", "Post_pmerq_Focus_Avg", "Post_pmerq_Distract_Avg", "Post_pmerq_AD_Avg")

# Identify condition levels (assuming exactly two conditions)
cond_levels <- unique(purrble_wide$condition)
cond_levels <- cond_levels[!is.na(cond_levels)]
if (length(cond_levels) != 2) {
  stop("This code expects exactly two conditions for the t-tests.")
}

# Split data by condition
data_cond1 <- purrble_wide[purrble_wide$condition == cond_levels[1], ]
data_cond2 <- purrble_wide[purrble_wide$condition == cond_levels[2], ]

# Initialize a results data frame
results <- data.frame(
  Outcome = character(),
  Condition1 = character(),
  Condition1_N = numeric(),
  Condition1_Mean = numeric(),
  Condition1_SD = numeric(),
  Condition2 = character(),
  Condition2_N = numeric(),
  Condition2_Mean = numeric(),
  Condition2_SD = numeric(),
  df = numeric(),
  t = numeric(),
  p = numeric(),
  CI_Lower = numeric(),
  CI_Upper = numeric(),
  stringsAsFactors = FALSE
)

# Loop through each pre-test variable and run descriptives and t-test
for (var in pre_vars) {
  
  # Describe by condition
  desc1 <- describe(data_cond1[[var]])
  desc2 <- describe(data_cond2[[var]])
  
  # Check if we have valid data for both conditions
  if (desc1$n > 0 & desc2$n > 0) {
    # t-test
    tt <- t.test(purrble_wide[[var]] ~ purrble_wide$condition)
    
    # Extract info
    n1 <- desc1$n
    mean1 <- desc1$mean
    sd1 <- desc1$sd
    
    n2 <- desc2$n
    mean2 <- desc2$mean
    sd2 <- desc2$sd
    
    df_val <- tt$parameter
    t_val <- tt$statistic
    p_val <- tt$p.value
    ci_lower <- tt$conf.int[1]
    ci_upper <- tt$conf.int[2]
    
    # Add row to results
    results <- rbind(results, data.frame(
      Outcome = var,
      Condition1 = cond_levels[1],
      Condition1_N = n1,
      Condition1_Mean = mean1,
      Condition1_SD = sd1,
      Condition2 = cond_levels[2],
      Condition2_N = n2,
      Condition2_Mean = mean2,
      Condition2_SD = sd2,
      df = df_val,
      t = t_val,
      p = p_val,
      CI_Lower = ci_lower,
      CI_Upper = ci_upper,
      stringsAsFactors = FALSE
    ))
  }
}

cat("Baseline differences in study outcomes by condition\n\n")
## Baseline differences in study outcomes by condition
print(results)
##                     Outcome       Condition1 Condition1_N Condition1_Mean
## df         Pre_shqscreener1 Waitlist Control           77        2.426407
## df1        Pre_shqscreener2 Waitlist Control           77        1.805195
## df2        Pre_shqscreener3 Waitlist Control           77        1.374459
## df3           Pre_DERS8_Sum Waitlist Control           77       28.350649
## df4            Pre_GAD7_Sum Waitlist Control           77       13.649351
## df5            Pre_PHQ9_Sum Waitlist Control           77       14.675325
## df6        Pre_SHS_Pathways Waitlist Control           74       13.783784
## df7          Pre_SHS_Agency Waitlist Control           74       11.202703
## df8       Pre_SHS_TotalHope Waitlist Control           74       24.986486
## df9            Pre_ucla_Sum Waitlist Control           74        7.270270
## df10    Pre_pmerq_Focus_Avg Waitlist Control           74        2.834459
## df11 Pre_pmerq_Distract_Avg Waitlist Control           74        4.313514
## df12       Pre_pmerq_AD_Avg Waitlist Control           74        3.573986
##      Condition1_SD        Condition2 Condition2_N Condition2_Mean Condition2_SD
## df       0.8837774 Purrble Treatment           76        2.307018     0.7750998
## df1      0.8339483 Purrble Treatment           76        1.712719     0.7371611
## df2      0.6130619 Purrble Treatment           76        1.267544     0.3840129
## df3      4.3003625 Purrble Treatment           76       27.918860     5.1017421
## df4      3.7141645 Purrble Treatment           76       13.780702     4.2495499
## df5      4.2195673 Purrble Treatment           76       15.390351     4.9000796
## df6      3.9940719 Purrble Treatment           75       12.806667     4.5268667
## df7      5.0962778 Purrble Treatment           75       10.220000     4.7414503
## df8      8.2237432 Purrble Treatment           75       23.026667     8.3649419
## df9      1.3578518 Purrble Treatment           74        6.918919     1.8339026
## df10     1.0800788 Purrble Treatment           75        2.641667     1.0369714
## df11     1.0979837 Purrble Treatment           75        4.132000     1.1549143
## df12     0.9636318 Purrble Treatment           75        3.386833     0.8766801
##            df          t         p   CI_Lower  CI_Upper
## df   148.9466  0.8886754 0.3756105 -0.1460795 0.3848583
## df1  149.2051  0.7269566 0.4683916 -0.1588886 0.3438396
## df2  127.9451  1.2944955 0.1978257 -0.0565081 0.2703381
## df3  146.1480  0.5656812 0.5724780 -1.0767605 1.9403399
## df4  147.8107 -0.2034630 0.8390530 -1.4071046 1.1444024
## df5  147.1651 -0.9666385 0.3353107 -2.1768400 0.7467876
## df6  145.2059  1.3975805 0.1643707 -0.4047063 2.3589405
## df7  145.9327  1.2182135 0.2251087 -0.6115726 2.5769780
## df8  146.9982  1.4421041 0.1514002 -0.7258820 4.6455216
## df9  134.5433  1.3245408 0.1875690 -0.1732729 0.8759756
## df10 146.5693  1.1112036 0.2683002 -0.1500902 0.5356758
## df11 146.7989  0.9832994 0.3270779 -0.1832962 0.5463232
## df12 145.3132  1.2395598 0.2171364 -0.1112543 0.4855606

ANCOVA Of all outcomes of interest: Examining Intervention Outcome Controlling for Baseline Covariates

# Assuming pre_vars and purrble_wide are defined
pre_vars <- c("Pre_shqscreener1", "Pre_shqscreener2", "Pre_shqscreener3",
              "Pre_DERS8_Sum", "Pre_GAD7_Sum", "Pre_PHQ9_Sum",
              "Pre_SHS_Pathways", "Pre_SHS_Agency", "Pre_SHS_TotalHope",
              "Pre_ucla_Sum", "Pre_pmerq_Focus_Avg", "Pre_pmerq_Distract_Avg", "Pre_pmerq_AD_Avg")

# Identify condition levels
cond_levels <- unique(purrble_wide$condition)
cond_levels <- cond_levels[!is.na(cond_levels)]
if (length(cond_levels) != 2) {
  stop("This code expects exactly two conditions for the t-tests.")
}

cat("Baseline differences in study outcomes by condition\n\n")
## Baseline differences in study outcomes by condition
# Initialize a results data frame
results <- data.frame(
  Outcome = character(),
  Condition1 = character(),
  Condition1_N = numeric(),
  Condition1_Mean = numeric(),
  Condition1_SD = numeric(),
  Condition2 = character(),
  Condition2_N = numeric(),
  Condition2_Mean = numeric(),
  Condition2_SD = numeric(),
  df = numeric(),
  t = numeric(),
  p = numeric(),
  CI_Lower = numeric(),
  CI_Upper = numeric(),
  stringsAsFactors = FALSE
)

for (var in pre_vars) {
  # Extract data for both conditions
  cond1_data <- purrble_wide[purrble_wide$condition == cond_levels[1], var, drop = TRUE]
  cond2_data <- purrble_wide[purrble_wide$condition == cond_levels[2], var, drop = TRUE]
  
  # Compute descriptives
  cond1_n <- sum(!is.na(cond1_data))
  cond1_mean <- mean(cond1_data, na.rm = TRUE)
  cond1_sd <- sd(cond1_data, na.rm = TRUE)
  
  cond2_n <- sum(!is.na(cond2_data))
  cond2_mean <- mean(cond2_data, na.rm = TRUE)
  cond2_sd <- sd(cond2_data, na.rm = TRUE)
  
  # Only run t-test if both groups have data
  if (cond1_n > 0 & cond2_n > 0) {
    tt <- t.test(purrble_wide[[var]] ~ purrble_wide$condition)
    
    df_val <- tt$parameter
    t_val <- tt$statistic
    p_val <- tt$p.value
    ci_lower <- tt$conf.int[1]
    ci_upper <- tt$conf.int[2]
    
    results <- rbind(results, data.frame(
      Outcome = var,
      Condition1 = cond_levels[1],
      Condition1_N = cond1_n,
      Condition1_Mean = cond1_mean,
      Condition1_SD = cond1_sd,
      Condition2 = cond_levels[2],
      Condition2_N = cond2_n,
      Condition2_Mean = cond2_mean,
      Condition2_SD = cond2_sd,
      df = df_val,
      t = t_val,
      p = p_val,
      CI_Lower = ci_lower,
      CI_Upper = ci_upper,
      stringsAsFactors = FALSE
    ))
  }
}

print(results)
##                     Outcome       Condition1 Condition1_N Condition1_Mean
## df         Pre_shqscreener1 Waitlist Control           77        2.426407
## df1        Pre_shqscreener2 Waitlist Control           77        1.805195
## df2        Pre_shqscreener3 Waitlist Control           77        1.374459
## df3           Pre_DERS8_Sum Waitlist Control           77       28.350649
## df4            Pre_GAD7_Sum Waitlist Control           77       13.649351
## df5            Pre_PHQ9_Sum Waitlist Control           77       14.675325
## df6        Pre_SHS_Pathways Waitlist Control           74       13.783784
## df7          Pre_SHS_Agency Waitlist Control           74       11.202703
## df8       Pre_SHS_TotalHope Waitlist Control           74       24.986486
## df9            Pre_ucla_Sum Waitlist Control           74        7.270270
## df10    Pre_pmerq_Focus_Avg Waitlist Control           74        2.834459
## df11 Pre_pmerq_Distract_Avg Waitlist Control           74        4.313514
## df12       Pre_pmerq_AD_Avg Waitlist Control           74        3.573986
##      Condition1_SD        Condition2 Condition2_N Condition2_Mean Condition2_SD
## df       0.8837774 Purrble Treatment           76        2.307018     0.7750998
## df1      0.8339483 Purrble Treatment           76        1.712719     0.7371611
## df2      0.6130619 Purrble Treatment           76        1.267544     0.3840129
## df3      4.3003625 Purrble Treatment           76       27.918860     5.1017421
## df4      3.7141645 Purrble Treatment           76       13.780702     4.2495499
## df5      4.2195673 Purrble Treatment           76       15.390351     4.9000796
## df6      3.9940719 Purrble Treatment           75       12.806667     4.5268667
## df7      5.0962778 Purrble Treatment           75       10.220000     4.7414503
## df8      8.2237432 Purrble Treatment           75       23.026667     8.3649419
## df9      1.3578518 Purrble Treatment           74        6.918919     1.8339026
## df10     1.0800788 Purrble Treatment           75        2.641667     1.0369714
## df11     1.0979837 Purrble Treatment           75        4.132000     1.1549143
## df12     0.9636318 Purrble Treatment           75        3.386833     0.8766801
##            df          t         p   CI_Lower  CI_Upper
## df   148.9466  0.8886754 0.3756105 -0.1460795 0.3848583
## df1  149.2051  0.7269566 0.4683916 -0.1588886 0.3438396
## df2  127.9451  1.2944955 0.1978257 -0.0565081 0.2703381
## df3  146.1480  0.5656812 0.5724780 -1.0767605 1.9403399
## df4  147.8107 -0.2034630 0.8390530 -1.4071046 1.1444024
## df5  147.1651 -0.9666385 0.3353107 -2.1768400 0.7467876
## df6  145.2059  1.3975805 0.1643707 -0.4047063 2.3589405
## df7  145.9327  1.2182135 0.2251087 -0.6115726 2.5769780
## df8  146.9982  1.4421041 0.1514002 -0.7258820 4.6455216
## df9  134.5433  1.3245408 0.1875690 -0.1732729 0.8759756
## df10 146.5693  1.1112036 0.2683002 -0.1500902 0.5356758
## df11 146.7989  0.9832994 0.3270779 -0.1832962 0.5463232
## df12 145.3132  1.2395598 0.2171364 -0.1112543 0.4855606
# Define pre-test and post-test variables
pre_vars <- c("Pre_shqscreener1", "Pre_shqscreener2", "Pre_shqscreener3",
              "Pre_DERS8_Sum", "Pre_GAD7_Sum", "Pre_PHQ9_Sum",
              "Pre_SHS_Pathways", "Pre_SHS_Agency", "Pre_SHS_TotalHope",
              "Pre_ucla_Sum", "Pre_pmerq_Focus_Avg", "Pre_pmerq_Distract_Avg", "Pre_pmerq_AD_Avg")

post_vars <- c("Post_shqscreener1", "Post_shqscreener2", "Post_shqscreener3",
               "Post_DERS8_Sum", "Post_GAD7_Sum", "Post_PHQ9_Sum",
               "Post_SHS_Pathways", "Post_SHS_Agency", "Post_SHS_TotalHope",
               "Post_ucla_Sum", "Post_pmerq_Focus_Avg", "Post_pmerq_Distract_Avg", "Post_pmerq_AD_Avg")

# Run ANCOVAs for each post-test variable controlling for the corresponding pre-test variable
for (post_var in post_vars) {
  # Identify the corresponding pre variable
  pre_var <- sub("^Post_", "Pre_", post_var)

  # Ensure that both variables exist in the dataset
  if (!(pre_var %in% names(purrble_wide))) {
    cat("No corresponding pre-test variable found for:", post_var, "\n")
    next
  }

  # Fit the ANCOVA model
  # Model: Post_Test_Outcome ~ condition + Pre_Test_Outcome
  formula_str <- paste(post_var, "~ condition +", pre_var)
  model <- aov(as.formula(formula_str), data = purrble_wide)
  
  # Calculate Means and SDs by condition for the post-test variable
  cond_means <- tapply(purrble_wide[[post_var]], purrble_wide$condition, mean, na.rm = TRUE)
  cond_sd <- tapply(purrble_wide[[post_var]], purrble_wide$condition, sd, na.rm = TRUE)
  
  # Print the header
  cat("\n---------------------------------------\n")
  cat("ANCOVA for:", post_var, "controlling for", pre_var, "\n")
  cat("---------------------------------------\n")

  # Print Means and SDs by condition
  cat("Condition-level Descriptives for", post_var, ":\n")
  cond_levels <- names(cond_means)
  for (lvl in cond_levels) {
    cat(lvl, ": Mean =", round(cond_means[lvl], 2), "SD =", round(cond_sd[lvl], 2), "\n")
  }
  cat("\n")

  # Print the model summary
  print(summary(model))
}
## 
## ---------------------------------------
## ANCOVA for: Post_shqscreener1 controlling for Pre_shqscreener1 
## ---------------------------------------
## Condition-level Descriptives for Post_shqscreener1 :
## Waitlist Control : Mean = 2.11 SD = 0.94 
## Purrble Treatment : Mean = 2.04 SD = 0.92 
## 
##                   Df Sum Sq Mean Sq F value Pr(>F)    
## condition          1   0.17    0.17   0.342   0.56    
## Pre_shqscreener1   1  51.71   51.71 102.074 <2e-16 ***
## Residuals        138  69.91    0.51                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
## 
## ---------------------------------------
## ANCOVA for: Post_shqscreener2 controlling for Pre_shqscreener2 
## ---------------------------------------
## Condition-level Descriptives for Post_shqscreener2 :
## Waitlist Control : Mean = 1.72 SD = 0.78 
## Purrble Treatment : Mean = 1.7 SD = 0.8 
## 
##                   Df Sum Sq Mean Sq F value   Pr(>F)    
## condition          1   0.01    0.01   0.014    0.905    
## Pre_shqscreener2   1  33.44   33.44  86.447 2.87e-16 ***
## Residuals        138  53.38    0.39                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
## 
## ---------------------------------------
## ANCOVA for: Post_shqscreener3 controlling for Pre_shqscreener3 
## ---------------------------------------
## Condition-level Descriptives for Post_shqscreener3 :
## Waitlist Control : Mean = 1.3 SD = 0.53 
## Purrble Treatment : Mean = 1.27 SD = 0.53 
## 
##                   Df Sum Sq Mean Sq F value   Pr(>F)    
## condition          1   0.06   0.063   0.273    0.602    
## Pre_shqscreener3   1   7.94   7.938  34.587 2.93e-08 ***
## Residuals        138  31.67   0.230                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
## 
## ---------------------------------------
## ANCOVA for: Post_DERS8_Sum controlling for Pre_DERS8_Sum 
## ---------------------------------------
## Condition-level Descriptives for Post_DERS8_Sum :
## Waitlist Control : Mean = 28.58 SD = 6.48 
## Purrble Treatment : Mean = 25.26 SD = 7.8 
## 
##                Df Sum Sq Mean Sq F value   Pr(>F)    
## condition       1    410   410.4   13.07 0.000419 ***
## Pre_DERS8_Sum   1   2779  2778.5   88.53  < 2e-16 ***
## Residuals     138   4331    31.4                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
## 
## ---------------------------------------
## ANCOVA for: Post_GAD7_Sum controlling for Pre_GAD7_Sum 
## ---------------------------------------
## Condition-level Descriptives for Post_GAD7_Sum :
## Waitlist Control : Mean = 13.22 SD = 4.43 
## Purrble Treatment : Mean = 12 SD = 5.47 
## 
##               Df Sum Sq Mean Sq F value   Pr(>F)    
## condition      1     54    54.0   3.498   0.0636 .  
## Pre_GAD7_Sum   1   1311  1311.2  84.884 4.68e-16 ***
## Residuals    138   2132    15.4                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
## 
## ---------------------------------------
## ANCOVA for: Post_PHQ9_Sum controlling for Pre_PHQ9_Sum 
## ---------------------------------------
## Condition-level Descriptives for Post_PHQ9_Sum :
## Waitlist Control : Mean = 15.16 SD = 5.89 
## Purrble Treatment : Mean = 13.44 SD = 6.66 
## 
##               Df Sum Sq Mean Sq F value Pr(>F)    
## condition      1  110.5   110.5   6.195  0.014 *  
## Pre_PHQ9_Sum   1 3034.1  3034.1 170.110 <2e-16 ***
## Residuals    138 2461.4    17.8                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
## 
## ---------------------------------------
## ANCOVA for: Post_SHS_Pathways controlling for Pre_SHS_Pathways 
## ---------------------------------------
## Condition-level Descriptives for Post_SHS_Pathways :
## Waitlist Control : Mean = 14.84 SD = 4.2 
## Purrble Treatment : Mean = 14.47 SD = 4.46 
## 
##                   Df Sum Sq Mean Sq F value   Pr(>F)    
## condition          1    9.1     9.1   0.642    0.424    
## Pre_SHS_Pathways   1  602.4   602.4  42.711 1.45e-09 ***
## Residuals        125 1763.0    14.1                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 26 observations deleted due to missingness
## 
## ---------------------------------------
## ANCOVA for: Post_SHS_Agency controlling for Pre_SHS_Agency 
## ---------------------------------------
## Condition-level Descriptives for Post_SHS_Agency :
## Waitlist Control : Mean = 12.72 SD = 5.06 
## Purrble Treatment : Mean = 12.52 SD = 5.42 
## 
##                 Df Sum Sq Mean Sq F value   Pr(>F)    
## condition        1    3.5     3.5   0.172    0.679    
## Pre_SHS_Agency   1  922.2   922.2  44.821 6.53e-10 ***
## Residuals      125 2571.8    20.6                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 26 observations deleted due to missingness
## 
## ---------------------------------------
## ANCOVA for: Post_SHS_TotalHope controlling for Pre_SHS_TotalHope 
## ---------------------------------------
## Condition-level Descriptives for Post_SHS_TotalHope :
## Waitlist Control : Mean = 27.57 SD = 8.63 
## Purrble Treatment : Mean = 26.98 SD = 9.03 
## 
##                    Df Sum Sq Mean Sq F value   Pr(>F)    
## condition           1     24    23.9   0.421    0.518    
## Pre_SHS_TotalHope   1   2786  2786.1  49.027 1.37e-10 ***
## Residuals         125   7103    56.8                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 26 observations deleted due to missingness
## 
## ---------------------------------------
## ANCOVA for: Post_ucla_Sum controlling for Pre_ucla_Sum 
## ---------------------------------------
## Condition-level Descriptives for Post_ucla_Sum :
## Waitlist Control : Mean = 6.91 SD = 1.57 
## Purrble Treatment : Mean = 6.68 SD = 1.84 
## 
##               Df Sum Sq Mean Sq F value Pr(>F)    
## condition      1   1.76    1.76   1.092  0.298    
## Pre_ucla_Sum   1 169.72  169.72 105.241 <2e-16 ***
## Residuals    124 199.98    1.61                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 27 observations deleted due to missingness
## 
## ---------------------------------------
## ANCOVA for: Post_pmerq_Focus_Avg controlling for Pre_pmerq_Focus_Avg 
## ---------------------------------------
## Condition-level Descriptives for Post_pmerq_Focus_Avg :
## Waitlist Control : Mean = 2.89 SD = 1.18 
## Purrble Treatment : Mean = 3.1 SD = 1.21 
## 
##                      Df Sum Sq Mean Sq F value Pr(>F)    
## condition             1   0.92    0.92   1.128   0.29    
## Pre_pmerq_Focus_Avg   1  77.79   77.79  95.442 <2e-16 ***
## Residuals           124 101.06    0.82                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 27 observations deleted due to missingness
## 
## ---------------------------------------
## ANCOVA for: Post_pmerq_Distract_Avg controlling for Pre_pmerq_Distract_Avg 
## ---------------------------------------
## Condition-level Descriptives for Post_pmerq_Distract_Avg :
## Waitlist Control : Mean = 4.26 SD = 1.05 
## Purrble Treatment : Mean = 4.42 SD = 1.06 
## 
##                         Df Sum Sq Mean Sq F value   Pr(>F)    
## condition                1   0.64    0.64    0.77    0.382    
## Pre_pmerq_Distract_Avg   1  35.83   35.83   42.88 1.39e-09 ***
## Residuals              124 103.64    0.84                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 27 observations deleted due to missingness
## 
## ---------------------------------------
## ANCOVA for: Post_pmerq_AD_Avg controlling for Pre_pmerq_AD_Avg 
## ---------------------------------------
## Condition-level Descriptives for Post_pmerq_AD_Avg :
## Waitlist Control : Mean = 3.58 SD = 0.97 
## Purrble Treatment : Mean = 3.76 SD = 0.93 
## 
##                   Df Sum Sq Mean Sq F value Pr(>F)    
## condition          1   0.78    0.78   1.492  0.224    
## Pre_pmerq_AD_Avg   1  49.29   49.29  94.794 <2e-16 ***
## Residuals        124  64.47    0.52                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 27 observations deleted due to missingness
library(effectsize)
## 
## Attaching package: 'effectsize'
## The following object is masked from 'package:psych':
## 
##     phi
# Define pre-test and post-test variables
pre_vars <- c("Pre_shqscreener1", "Pre_shqscreener2", "Pre_shqscreener3",
              "Pre_DERS8_Sum", "Pre_GAD7_Sum", "Pre_PHQ9_Sum",
              "Pre_SHS_Pathways", "Pre_SHS_Agency", "Pre_SHS_TotalHope",
              "Pre_ucla_Sum", "Pre_pmerq_Focus_Avg", "Pre_pmerq_Distract_Avg", "Pre_pmerq_AD_Avg")

post_vars <- c("Post_shqscreener1", "Post_shqscreener2", "Post_shqscreener3",
               "Post_DERS8_Sum", "Post_GAD7_Sum", "Post_PHQ9_Sum",
               "Post_SHS_Pathways", "Post_SHS_Agency", "Post_SHS_TotalHope",
               "Post_ucla_Sum", "Post_pmerq_Focus_Avg", "Post_pmerq_Distract_Avg", "Post_pmerq_AD_Avg")

# Run ANCOVAs for each post-test variable controlling for the corresponding pre-test variable
for (post_var in post_vars) {
  # Identify the corresponding pre variable
  pre_var <- sub("^Post_", "Pre_", post_var)

  # Ensure that both variables exist in the dataset
  if (!(pre_var %in% names(purrble_wide))) {
    cat("No corresponding pre-test variable found for:", post_var, "\n")
    next
  }

  # Fit the ANCOVA model
  formula_str <- paste(post_var, "~ condition +", pre_var)
  model <- aov(as.formula(formula_str), data = purrble_wide)

  # Print a header and the model summary
  cat("\n---------------------------------------\n")
  cat("ANCOVA for:", post_var, "controlling for", pre_var, "\n")
  cat("---------------------------------------\n")
  print(summary(model))
  
  # Compute partial eta squared
  eta_sq_results <- eta_squared(model, partial = TRUE)
  
  # Compute Cohen's f (partial)
  # By default, cohens_f() returns partial effects for each term in the model
  f_results <- cohens_f(model, partial = TRUE)
  
  cat("\nPartial Eta Squared:\n")
  print(eta_sq_results)
  
  cat("\nCohen's f (Partial):\n")
  print(f_results)
}
## 
## ---------------------------------------
## ANCOVA for: Post_shqscreener1 controlling for Pre_shqscreener1 
## ---------------------------------------
##                   Df Sum Sq Mean Sq F value Pr(>F)    
## condition          1   0.17    0.17   0.342   0.56    
## Pre_shqscreener1   1  51.71   51.71 102.074 <2e-16 ***
## Residuals        138  69.91    0.51                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
## 
## Partial Eta Squared:
## # Effect Size for ANOVA (Type I)
## 
## Parameter        | Eta2 (partial) |       95% CI
## ------------------------------------------------
## condition        |       2.47e-03 | [0.00, 1.00]
## Pre_shqscreener1 |           0.43 | [0.33, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
## Cohen's f (Partial):
## # Effect Size for ANOVA (Type I)
## 
## Parameter        | Cohen's f (partial) |      95% CI
## ----------------------------------------------------
## condition        |                0.05 | [0.00, Inf]
## Pre_shqscreener1 |                0.86 | [0.69, Inf]
## 
## - One-sided CIs: upper bound fixed at [Inf].
## ---------------------------------------
## ANCOVA for: Post_shqscreener2 controlling for Pre_shqscreener2 
## ---------------------------------------
##                   Df Sum Sq Mean Sq F value   Pr(>F)    
## condition          1   0.01    0.01   0.014    0.905    
## Pre_shqscreener2   1  33.44   33.44  86.447 2.87e-16 ***
## Residuals        138  53.38    0.39                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
## 
## Partial Eta Squared:
## # Effect Size for ANOVA (Type I)
## 
## Parameter        | Eta2 (partial) |       95% CI
## ------------------------------------------------
## condition        |       1.03e-04 | [0.00, 1.00]
## Pre_shqscreener2 |           0.39 | [0.28, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
## Cohen's f (Partial):
## # Effect Size for ANOVA (Type I)
## 
## Parameter        | Cohen's f (partial) |      95% CI
## ----------------------------------------------------
## condition        |                0.01 | [0.00, Inf]
## Pre_shqscreener2 |                0.79 | [0.63, Inf]
## 
## - One-sided CIs: upper bound fixed at [Inf].
## ---------------------------------------
## ANCOVA for: Post_shqscreener3 controlling for Pre_shqscreener3 
## ---------------------------------------
##                   Df Sum Sq Mean Sq F value   Pr(>F)    
## condition          1   0.06   0.063   0.273    0.602    
## Pre_shqscreener3   1   7.94   7.938  34.587 2.93e-08 ***
## Residuals        138  31.67   0.230                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
## 
## Partial Eta Squared:
## # Effect Size for ANOVA (Type I)
## 
## Parameter        | Eta2 (partial) |       95% CI
## ------------------------------------------------
## condition        |       1.97e-03 | [0.00, 1.00]
## Pre_shqscreener3 |           0.20 | [0.11, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
## Cohen's f (Partial):
## # Effect Size for ANOVA (Type I)
## 
## Parameter        | Cohen's f (partial) |      95% CI
## ----------------------------------------------------
## condition        |                0.04 | [0.00, Inf]
## Pre_shqscreener3 |                0.50 | [0.35, Inf]
## 
## - One-sided CIs: upper bound fixed at [Inf].
## ---------------------------------------
## ANCOVA for: Post_DERS8_Sum controlling for Pre_DERS8_Sum 
## ---------------------------------------
##                Df Sum Sq Mean Sq F value   Pr(>F)    
## condition       1    410   410.4   13.07 0.000419 ***
## Pre_DERS8_Sum   1   2779  2778.5   88.53  < 2e-16 ***
## Residuals     138   4331    31.4                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
## 
## Partial Eta Squared:
## # Effect Size for ANOVA (Type I)
## 
## Parameter     | Eta2 (partial) |       95% CI
## ---------------------------------------------
## condition     |           0.09 | [0.03, 1.00]
## Pre_DERS8_Sum |           0.39 | [0.29, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
## Cohen's f (Partial):
## # Effect Size for ANOVA (Type I)
## 
## Parameter     | Cohen's f (partial) |      95% CI
## -------------------------------------------------
## condition     |                0.31 | [0.16, Inf]
## Pre_DERS8_Sum |                0.80 | [0.64, Inf]
## 
## - One-sided CIs: upper bound fixed at [Inf].
## ---------------------------------------
## ANCOVA for: Post_GAD7_Sum controlling for Pre_GAD7_Sum 
## ---------------------------------------
##               Df Sum Sq Mean Sq F value   Pr(>F)    
## condition      1     54    54.0   3.498   0.0636 .  
## Pre_GAD7_Sum   1   1311  1311.2  84.884 4.68e-16 ***
## Residuals    138   2132    15.4                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
## 
## Partial Eta Squared:
## # Effect Size for ANOVA (Type I)
## 
## Parameter    | Eta2 (partial) |       95% CI
## --------------------------------------------
## condition    |           0.02 | [0.00, 1.00]
## Pre_GAD7_Sum |           0.38 | [0.28, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
## Cohen's f (Partial):
## # Effect Size for ANOVA (Type I)
## 
## Parameter    | Cohen's f (partial) |      95% CI
## ------------------------------------------------
## condition    |                0.16 | [0.00, Inf]
## Pre_GAD7_Sum |                0.78 | [0.62, Inf]
## 
## - One-sided CIs: upper bound fixed at [Inf].
## ---------------------------------------
## ANCOVA for: Post_PHQ9_Sum controlling for Pre_PHQ9_Sum 
## ---------------------------------------
##               Df Sum Sq Mean Sq F value Pr(>F)    
## condition      1  110.5   110.5   6.195  0.014 *  
## Pre_PHQ9_Sum   1 3034.1  3034.1 170.110 <2e-16 ***
## Residuals    138 2461.4    17.8                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
## 
## Partial Eta Squared:
## # Effect Size for ANOVA (Type I)
## 
## Parameter    | Eta2 (partial) |       95% CI
## --------------------------------------------
## condition    |           0.04 | [0.00, 1.00]
## Pre_PHQ9_Sum |           0.55 | [0.46, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
## Cohen's f (Partial):
## # Effect Size for ANOVA (Type I)
## 
## Parameter    | Cohen's f (partial) |      95% CI
## ------------------------------------------------
## condition    |                0.21 | [0.07, Inf]
## Pre_PHQ9_Sum |                1.11 | [0.93, Inf]
## 
## - One-sided CIs: upper bound fixed at [Inf].
## ---------------------------------------
## ANCOVA for: Post_SHS_Pathways controlling for Pre_SHS_Pathways 
## ---------------------------------------
##                   Df Sum Sq Mean Sq F value   Pr(>F)    
## condition          1    9.1     9.1   0.642    0.424    
## Pre_SHS_Pathways   1  602.4   602.4  42.711 1.45e-09 ***
## Residuals        125 1763.0    14.1                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 26 observations deleted due to missingness
## 
## Partial Eta Squared:
## # Effect Size for ANOVA (Type I)
## 
## Parameter        | Eta2 (partial) |       95% CI
## ------------------------------------------------
## condition        |       5.11e-03 | [0.00, 1.00]
## Pre_SHS_Pathways |           0.25 | [0.15, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
## Cohen's f (Partial):
## # Effect Size for ANOVA (Type I)
## 
## Parameter        | Cohen's f (partial) |      95% CI
## ----------------------------------------------------
## condition        |                0.07 | [0.00, Inf]
## Pre_SHS_Pathways |                0.58 | [0.42, Inf]
## 
## - One-sided CIs: upper bound fixed at [Inf].
## ---------------------------------------
## ANCOVA for: Post_SHS_Agency controlling for Pre_SHS_Agency 
## ---------------------------------------
##                 Df Sum Sq Mean Sq F value   Pr(>F)    
## condition        1    3.5     3.5   0.172    0.679    
## Pre_SHS_Agency   1  922.2   922.2  44.821 6.53e-10 ***
## Residuals      125 2571.8    20.6                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 26 observations deleted due to missingness
## 
## Partial Eta Squared:
## # Effect Size for ANOVA (Type I)
## 
## Parameter      | Eta2 (partial) |       95% CI
## ----------------------------------------------
## condition      |       1.37e-03 | [0.00, 1.00]
## Pre_SHS_Agency |           0.26 | [0.16, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
## Cohen's f (Partial):
## # Effect Size for ANOVA (Type I)
## 
## Parameter      | Cohen's f (partial) |      95% CI
## --------------------------------------------------
## condition      |                0.04 | [0.00, Inf]
## Pre_SHS_Agency |                0.60 | [0.44, Inf]
## 
## - One-sided CIs: upper bound fixed at [Inf].
## ---------------------------------------
## ANCOVA for: Post_SHS_TotalHope controlling for Pre_SHS_TotalHope 
## ---------------------------------------
##                    Df Sum Sq Mean Sq F value   Pr(>F)    
## condition           1     24    23.9   0.421    0.518    
## Pre_SHS_TotalHope   1   2786  2786.1  49.027 1.37e-10 ***
## Residuals         125   7103    56.8                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 26 observations deleted due to missingness
## 
## Partial Eta Squared:
## # Effect Size for ANOVA (Type I)
## 
## Parameter         | Eta2 (partial) |       95% CI
## -------------------------------------------------
## condition         |       3.35e-03 | [0.00, 1.00]
## Pre_SHS_TotalHope |           0.28 | [0.18, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
## Cohen's f (Partial):
## # Effect Size for ANOVA (Type I)
## 
## Parameter         | Cohen's f (partial) |      95% CI
## -----------------------------------------------------
## condition         |                0.06 | [0.00, Inf]
## Pre_SHS_TotalHope |                0.63 | [0.46, Inf]
## 
## - One-sided CIs: upper bound fixed at [Inf].
## ---------------------------------------
## ANCOVA for: Post_ucla_Sum controlling for Pre_ucla_Sum 
## ---------------------------------------
##               Df Sum Sq Mean Sq F value Pr(>F)    
## condition      1   1.76    1.76   1.092  0.298    
## Pre_ucla_Sum   1 169.72  169.72 105.241 <2e-16 ***
## Residuals    124 199.98    1.61                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 27 observations deleted due to missingness
## 
## Partial Eta Squared:
## # Effect Size for ANOVA (Type I)
## 
## Parameter    | Eta2 (partial) |       95% CI
## --------------------------------------------
## condition    |       8.73e-03 | [0.00, 1.00]
## Pre_ucla_Sum |           0.46 | [0.36, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
## Cohen's f (Partial):
## # Effect Size for ANOVA (Type I)
## 
## Parameter    | Cohen's f (partial) |      95% CI
## ------------------------------------------------
## condition    |                0.09 | [0.00, Inf]
## Pre_ucla_Sum |                0.92 | [0.74, Inf]
## 
## - One-sided CIs: upper bound fixed at [Inf].
## ---------------------------------------
## ANCOVA for: Post_pmerq_Focus_Avg controlling for Pre_pmerq_Focus_Avg 
## ---------------------------------------
##                      Df Sum Sq Mean Sq F value Pr(>F)    
## condition             1   0.92    0.92   1.128   0.29    
## Pre_pmerq_Focus_Avg   1  77.79   77.79  95.442 <2e-16 ***
## Residuals           124 101.06    0.82                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 27 observations deleted due to missingness
## 
## Partial Eta Squared:
## # Effect Size for ANOVA (Type I)
## 
## Parameter           | Eta2 (partial) |       95% CI
## ---------------------------------------------------
## condition           |       9.02e-03 | [0.00, 1.00]
## Pre_pmerq_Focus_Avg |           0.43 | [0.33, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
## Cohen's f (Partial):
## # Effect Size for ANOVA (Type I)
## 
## Parameter           | Cohen's f (partial) |      95% CI
## -------------------------------------------------------
## condition           |                0.10 | [0.00, Inf]
## Pre_pmerq_Focus_Avg |                0.88 | [0.70, Inf]
## 
## - One-sided CIs: upper bound fixed at [Inf].
## ---------------------------------------
## ANCOVA for: Post_pmerq_Distract_Avg controlling for Pre_pmerq_Distract_Avg 
## ---------------------------------------
##                         Df Sum Sq Mean Sq F value   Pr(>F)    
## condition                1   0.64    0.64    0.77    0.382    
## Pre_pmerq_Distract_Avg   1  35.83   35.83   42.88 1.39e-09 ***
## Residuals              124 103.64    0.84                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 27 observations deleted due to missingness
## 
## Partial Eta Squared:
## # Effect Size for ANOVA (Type I)
## 
## Parameter              | Eta2 (partial) |       95% CI
## ------------------------------------------------------
## condition              |       6.17e-03 | [0.00, 1.00]
## Pre_pmerq_Distract_Avg |           0.26 | [0.15, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
## Cohen's f (Partial):
## # Effect Size for ANOVA (Type I)
## 
## Parameter              | Cohen's f (partial) |      95% CI
## ----------------------------------------------------------
## condition              |                0.08 | [0.00, Inf]
## Pre_pmerq_Distract_Avg |                0.59 | [0.43, Inf]
## 
## - One-sided CIs: upper bound fixed at [Inf].
## ---------------------------------------
## ANCOVA for: Post_pmerq_AD_Avg controlling for Pre_pmerq_AD_Avg 
## ---------------------------------------
##                   Df Sum Sq Mean Sq F value Pr(>F)    
## condition          1   0.78    0.78   1.492  0.224    
## Pre_pmerq_AD_Avg   1  49.29   49.29  94.794 <2e-16 ***
## Residuals        124  64.47    0.52                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 27 observations deleted due to missingness
## 
## Partial Eta Squared:
## # Effect Size for ANOVA (Type I)
## 
## Parameter        | Eta2 (partial) |       95% CI
## ------------------------------------------------
## condition        |           0.01 | [0.00, 1.00]
## Pre_pmerq_AD_Avg |           0.43 | [0.33, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
## Cohen's f (Partial):
## # Effect Size for ANOVA (Type I)
## 
## Parameter        | Cohen's f (partial) |      95% CI
## ----------------------------------------------------
## condition        |                0.11 | [0.00, Inf]
## Pre_pmerq_AD_Avg |                0.87 | [0.70, Inf]
## 
## - One-sided CIs: upper bound fixed at [Inf].

Post-test Logistic Regression to Investigate Intervention Effects on Self-Harm Outcomes

library(dplyr)
library(gtsummary)   
library(broom) 

#----------------------------------------------------------
# 1) Logistic regression for SHQ1 at Week 12
#    controlling for Week 2 SHQ1 and Condition
#----------------------------------------------------------
model_shq1 <- glm(
  SHQ1_12 ~ condition + SHQ1_2, 
  data = purrble_wide, 
  family = binomial
)

#----------------------------------------------------------
# 2) Logistic regression for SHQ2 at Week 12
#    controlling for Week 2 SHQ2 and Condition
#----------------------------------------------------------
model_shq2 <- glm(
  SHQ2_12 ~ condition + SHQ2_2, 
  data = purrble_wide, 
  family = binomial
)

#----------------------------------------------------------
# 3) Logistic regression for SHQ3 at Week 12
#    controlling for Week 2 SHQ3 and Condition
#----------------------------------------------------------
model_shq3 <- glm(
  SHQ3_12 ~ condition + SHQ3_2, 
  data = purrble_wide, 
  family = binomial
)

#----------------------------------------------------------
# 4) Logistic regression for SHQ_Any at Week 12
#    controlling for Week 2 SHQ_Any and Condition
#----------------------------------------------------------
model_shqAny <- glm(
  SHQ_Any_12 ~ condition + SHQ_Any_2, 
  data = purrble_wide, 
  family = binomial
)

# Create gtsummary tables for each model, exponentiating for OR
tbl_shq1   <- tbl_regression(model_shq1, exponentiate = TRUE) %>%
  bold_labels() %>%
  add_significance_stars()

tbl_shq2   <- tbl_regression(model_shq2, exponentiate = TRUE) %>%
  bold_labels() %>%
  add_significance_stars()

tbl_shq3   <- tbl_regression(model_shq3, exponentiate = TRUE) %>%
  bold_labels() %>%
  add_significance_stars()

tbl_shqAny <- tbl_regression(model_shqAny, exponentiate = TRUE) %>%
  bold_labels() %>%
  add_significance_stars()

merged_tbl <- tbl_merge(
   tbls = list(tbl_shq1, tbl_shq2, tbl_shq3, tbl_shqAny),
   tab_spanner = c("SHQ1 Model", "SHQ2 Model", "SHQ3 Model", "SHQ_Any Model")
 )
 merged_tbl
Characteristic
SHQ1 Model
SHQ2 Model
SHQ3 Model
SHQ_Any Model
OR1,2 SE2 OR1,2 SE2 OR1,2 SE2 OR1,2 SE2
condition







    Waitlist Control
    Purrble Treatment 1.15 0.452 0.98 0.412 0.87 0.546 1.10 0.434
SHQ1_2 11.6*** 0.484





SHQ2_2

4.36*** 0.408



SHQ3_2



3.14* 0.559

SHQ_Any_2





5.83*** 0.486
1 *p<0.05; **p<0.01; ***p<0.001
2 OR = Odds Ratio, SE = Standard Error

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Cmd+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.