DSMB Analysis

Author

Samuel Blay Nguah MD

Published

December 1, 2024

Data preparation

Table 1 - Preparation

Show the code
df_table_1 <- 
    dget("pings_2_data_ready") %>% #labelled::look_for("adverse")
    filter(eventname == "Baseline") %>% 
    mutate(
        hosp_cat = case_when(
            datagrp %in% c(
                "CCTH SITE", "KATH SITE", "KORLE-BU SITE") ~ "Tertiary",
            datagrp %in% c(
                "KUMASI SOUTH HOSPITAL", "AGOGO SITE", "KNUST SITE") ~ "Secondary",
            datagrp %in% c(
                "ANKAASE SITE", "MANHYIA GOVT HOSPITAL", "KWADASO SITE", "TAFO SITE") ~ 
                "Primary"),
        maristat_2 = case_when(
            a_maristat == "Never Married"  ~ "Never Married",
            a_maristat %in% c("Currently Married", "Cohabitating") ~ 
                "Currently Married",
            a_maristat %in% c("Separated","Widow/Widower", "Divorced") ~ 
                "Previously married"),
        mod_rank_score = parse_number(as.character(x_ranking))) %>% 
    select(
        a_gender, a_maristat, a_formeduc, hosp_cat, a_religion, 
        maristat_2, a_domicile, a_income, ee_bmi_0, d_st_type, 
        d_st_type, mod_rank_score, arm) %>% 
    mutate(
        arm  = case_when(
        arm == "Arm 1- Intervention Arm" ~ "Intervention",
        arm == "Arm 2- Routine Care" ~ "Routine Care"))

Table 2 preparation

Show the code
df_temp <- 
    dget("pings_2_data_ready") %>% 
    filter(eventname == "Baseline") %>% 
    select(pid, arm)
    
df_table_2 <- 
    dget("df_pings2_bp_data") %>% 
    rename(pid = `RedCap ID`) %>% 
    full_join(df_temp) %>% 
    select(
        arm, ee_sbp_0 = sbp_m0,  ee_dbp_0 = dbp_m0, sbp_m1, 
        dbp_m1, ee_sbp_3 = sbp_m3, ee_dbp_3 = dbp_m3, sbp_m6, 
        dbp_m6, sbp_m9, dbp_m9, ee_sbp_12 = sbp_m12, 
        ee_dbp_12 = dbp_m12) %>% 
    mutate(
        arm  = case_when(
        arm == "Arm 1- Intervention Arm" ~ "Intervention",
        arm == "Arm 2- Routine Care" ~ "Routine Care"))
Joining with `by = join_by(pid)`

Table 3 preparation

Show the code
df_table_3_qol <- 
    dget("pings_2_data_ready") %>% #labelled::look_for("health")
    filter(eventname %in% c("Baseline", "Month12")) %>% 
    mutate(
        mobility = case_when(
            str_detect(
                p_mobility , "I have no problems in walking about") ~ "1",
            str_detect(
                p_mobility , "I have some problems in walking about") ~ "2",
            str_detect(
                p_mobility , "I am confined to bed") ~ "3")%>% 
            as.numeric(),
        selfcare = case_when(
            str_detect(
                p_selfcare , "I have no problems with self-care") ~ "1",
            str_detect(
                p_selfcare , "I have some problems with washing or") ~ "2",
            str_detect(
                p_selfcare , "I am unable to wash or dress myself") ~ "3")%>%
            as.numeric(),
        usual_act = case_when(
            str_detect(
                p_usual_act , "I have no problems with performing my") ~ "1",
            str_detect(
                p_usual_act , "I have some problems with performing") ~ "2",
            str_detect(
                p_usual_act , "I am unable to perform my usual activitie") ~
                "3")%>% 
            as.numeric(),
        pain_disc = case_when(
            str_detect(p_pain_disc , "I have no pain or discomfort") ~ "1",
            str_detect(
                p_pain_disc , "I have moderate pain or discomfort") ~ "2",
            str_detect(
                p_pain_disc , "I have extreme pain or discomfort") ~ "3") %>%
            as.numeric(),
        anxiety = case_when(
            str_detect(p_anxiety, "I am not anxious or depressed") ~ "1",
            str_detect(
                p_anxiety, "I am moderately anxious or depressed") ~ "2",
            str_detect(
                p_anxiety, "I am extremely anxious or depressed") ~ "3")%>% 
            as.numeric(),
        eq_5d = mobility + selfcare + usual_act + pain_disc + anxiety) %>% 
    select(pid, eq_5d, arm, eventname) %>% 
    pivot_wider(
        id_cols = pid, names_from = eventname, values_from = eq_5d) %>% 
    full_join(df_temp)
Joining with `by = join_by(pid)`
Show the code
df_table_3_hillbone <- 
    dget("pings_2_data_ready") %>%
    filter(eventname %in% c("Baseline", "Month12")) %>% 
    mutate(
        across(
            c(l_forget, l_decide, l_salty, l_shake, l_fasfood, l_appoint, 
            l_missched, l_prescrip, l_runout, l_skipmed, l_feelbet,
            l_feelsick, l_someone, l_careless), 
            .fns = ~factor(.x),
            .names = "{.col}_unclassed"),
        across(
            c(l_forget_unclassed, l_decide_unclassed, l_salty_unclassed, 
              l_shake_unclassed, l_fasfood_unclassed, l_appoint_unclassed, 
            l_missched_unclassed, l_prescrip_unclassed, l_runout_unclassed, 
            l_skipmed_unclassed, l_feelbet_unclassed, l_feelsick_unclassed, 
            l_someone_unclassed, l_careless_unclassed), 
            .fns = ~unclass(.x)),
        hillbone = (
            l_forget_unclassed + l_decide_unclassed + 
            l_salty_unclassed + l_shake_unclassed + 
            l_fasfood_unclassed + l_appoint_unclassed + 
            l_missched_unclassed + l_prescrip_unclassed + 
            l_runout_unclassed + l_skipmed_unclassed + 
            l_feelbet_unclassed + l_feelsick_unclassed + 
            l_someone_unclassed + l_careless_unclassed) %>%  
            as.numeric(),
        ) %>% 
    select(pid, hillbone, arm, eventname) %>% 
    pivot_wider(
        id_cols = pid, names_from = eventname, values_from = hillbone) %>% 
    full_join(df_temp)
Joining with `by = join_by(pid)`
Show the code
a <- function(x){
    as.character(x) %>% 
    str_to_sentence() %>% 
    ifelse(str_detect(x, "Nil"), "No", x)
    }

df_temp_2 <- 
    dget("pings_2_data_ready") %>% 
    filter(eventname == "Month12") %>% 
    select(kk_status, pid) %>% 
    mutate(status = kk_status == "Dead") %>% 
    select(pid, status)

df_adverse_event <-
    dget("pings_2_data_ready") %>% 
    select(
        starts_with("gg_events"), starts_with("gg_stroke"),
        starts_with("gg_heart"),  starts_with("gg_stemi"), 
        starts_with("gg_cdeath"), starts_with("gg_renalf"), 
        starts_with("gg_emerg"), eventname, arm, pid) %>% 
    filter(eventname == "Baseline") %>% 
    mutate(
        across(starts_with("gg_"), ~as.character(.x)),
        across(starts_with("gg_"), ~str_to_sentence(.x)),
        across(starts_with("gg_"), ~ifelse(.x == "", "0", .x)),
        across(starts_with("gg_"), ~ifelse(str_detect(.x, "Nil"), "0", .x)), 
        across(starts_with("gg_"), ~ifelse(str_detect(.x, "No"), "0", .x)),
        across(starts_with("gg_"), ~ifelse(str_detect(.x, "Nnil"), "0", .x)),
        across(starts_with("gg_"), ~ifelse(str_detect(.x, "N/a"), "0", .x)),
        across(starts_with("gg_"), ~ifelse(str_detect(.x, "Nik"), "0", .x)),
        across(starts_with("gg_"), ~ifelse(.x == "Ni", "0", .x)),
        across(starts_with("gg_"), ~ifelse(str_detect(.x, "X"), "0", .x)),
        across(starts_with("gg_"), ~ifelse(str_detect(.x, "Yes"), "1", .x)),
        across(starts_with("gg_"), ~ifelse(.x != "0", "1", .x)),
        across(starts_with("gg_"), ~as.numeric(.x))) %>% 
    rowwise() %>% 
    mutate(
        gg_stroke = gg_stroke_1 + gg_stroke_3 + 
            gg_stroke_6 + gg_stroke_9 + gg_stroke_12,
        gg_stemi = gg_stemi_0 + gg_stemi_1 + gg_stemi_3 + 
            gg_stemi_6 + gg_stemi_9 + gg_stemi_12,
        gg_cdeath = gg_cdeath_0 + gg_cdeath_1 + gg_cdeath_3 + 
            gg_cdeath_6 + gg_cdeath_9 + gg_cdeath_12) %>% 
    select(pid, arm, gg_stroke, gg_cdeath, gg_stemi) %>% 
    mutate(gg_stroke = ifelse(gg_stroke > 0, 1, gg_stroke)) %>% 
    full_join(df_temp_2) %>% 
    select(-pid)
Joining with `by = join_by(pid)`
Show the code
df_hpt_stroke_know <- 
    dget("pings_2_data_ready") %>%
    mutate(
        aa_bp_115_75_corrrect = ifelse(
            aa_bp_115_75 == "Normal", "Yes", "No"),
        aa_bp160_100_correct = ifelse(
            aa_bp160_100 == "High", "Yes", "No"),
        aa_hptlasts_correct = ifelse(
            aa_hptlasts == "The Rest of their Life", "Yes", "No"),
        aa_hptmeds_correct = ifelse(aa_hptmeds == "Everyday", "Yes", "No"),
        aa_losewght_correct = ifelse(aa_losewght == "Go Down", "Yes", "No"),
        aa_eatsalt_correct = ifelse(aa_eatsalt == "Go Down", "Yes", "No"),
        aa_hrtattack_correct = ifelse(aa_hrtattack == "Yes", "Yes", "No"),
        aa_cancer_correct = ifelse(aa_cancer == "No", "Yes", "No"),
        aa_stroke_correct = ifelse(aa_stroke == "Yes", "Yes", "No"),
        aa_kidneyp_correct = ifelse(aa_kidneyp == "Yes", "Yes", "No"),
        aa_highrisk_correct = ifelse(aa_highrisk == "Yes", "Yes", "No"),
        aa_headache_correct = ifelse(aa_headache == "No", "Yes", "No"),
        aa_feelgood_correct = ifelse(aa_feelgood == "Never", "Yes", "No"),
        aa_strokeris_correct = ifelse(
            aa_strokeris == "The Rest of Their Life", "Yes", "No"),
        aa_hkq = (aa_bp_115_75_corrrect == "Yes") + 
            (aa_bp160_100_correct == "Yes") +
            (aa_hptlasts_correct =="Yes") + 
            (aa_hptmeds_correct == "Yes") + 
            (aa_losewght_correct == "Yes") + 
            (aa_eatsalt_correct == "Yes") + 
            (aa_hrtattack_correct == "Yes") + 
            (aa_cancer_correct == "Yes") + 
            (aa_stroke_correct == "Yes") + 
            (aa_kidneyp_correct == "Yes") + 
            (aa_highrisk_correct == "Yes") + 
            (aa_headache_correct =="Yes") + 
            (aa_feelgood_correct =="Yes") + 
            (aa_strokeris_correct == "Yes")) %>% 
    select(arm, aa_hkq, eventname, pid) %>% 
    filter(eventname %in% c("Baseline","Month12")) %>% 
    pivot_wider(
        id_cols = pid, 
        values_from = aa_hkq, 
        names_from = eventname) %>% 
    full_join(df_temp) %>% 
    select(-pid)
Joining with `by = join_by(pid)`
Show the code
df_ranking <- 
    dget("pings_2_data_ready") %>%
    filter(eventname %in% c("Baseline","Month12")) %>%
    mutate(mod_rank_score = parse_number(as.character(x_ranking))) %>% 
    select(mod_rank_score, arm, eventname, pid) %>% 
    pivot_wider(
        id_cols = pid, 
        values_from = mod_rank_score, 
        names_from = eventname) %>% 
    full_join(df_temp) %>% 
    select(-pid)
Joining with `by = join_by(pid)`
Show the code
df_ranking
# A tibble: 500 × 3
   Baseline Month12 arm                    
      <dbl>   <dbl> <fct>                  
 1        4       2 Arm 2- Routine Care    
 2        4       3 Arm 1- Intervention Arm
 3        2       0 Arm 1- Intervention Arm
 4        2       1 Arm 1- Intervention Arm
 5        4       3 Arm 2- Routine Care    
 6        2       1 Arm 2- Routine Care    
 7        1       0 Arm 2- Routine Care    
 8        1       2 Arm 1- Intervention Arm
 9        2       1 Arm 2- Routine Care    
10        4       2 Arm 1- Intervention Arm
# ℹ 490 more rows

Table 1

Show the code
gtsummary::theme_gtsummary_compact()
Setting theme "Compact"
Show the code
df_table_1 %>% 
    gtsummary::tbl_summary(
        digits = gtsummary::all_categorical()~ c(0,1),
        statistic = gtsummary::all_categorical() ~ "{n} ({p})",
        missing_text = "Missing", 
        by = arm,
        label = list(
            hosp_cat = "Health Institution category",
            maristat_2 = "Marital Status",
            mod_rank_score = "Modified Ranking Score"),
        type = list(mod_rank_score ~ "continuous")) %>% 
    gtsummary::add_overall() %>% 
    gtsummary::add_p() %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::modify_caption(
        "**Table 1**: Demographic Characteristics of Study Participants") 
Table 1: Demographic Characteristics of Study Participants

Characteristic

Overall
N = 500

1

Intervention
N = 244

1

Routine Care
N = 256

1

p-value

2
Gender


0.5
    Male 281 (56.2) 141 (57.8) 140 (54.7)
    Female 219 (43.8) 103 (42.2) 116 (45.3)
Marital Status


0.5
    Never Married 23 (4.6) 11 (4.5) 12 (4.7)
    Currently Married 325 (65.0) 164 (67.2) 161 (62.9)
    Separated 38 (7.6) 22 (9.0) 16 (6.3)
    Widow/Widower 84 (16.8) 35 (14.3) 49 (19.1)
    Cohabitating 8 (1.6) 3 (1.2) 5 (2.0)
    Divorced 22 (4.4) 9 (3.7) 13 (5.1)
Level of Formal education


0.2
    None 49 (9.8) 17 (7.0) 32 (12.5)
    Primary 204 (40.8) 96 (39.3) 108 (42.2)
    Secondary 164 (32.8) 88 (36.1) 76 (29.7)
    Tertiary 72 (14.4) 37 (15.2) 35 (13.7)
    Postgraduate 11 (2.2) 6 (2.5) 5 (2.0)
Health Institution category


0.8
    Primary 148 (29.6) 73 (29.9) 75 (29.3)
    Secondary 119 (23.8) 55 (22.5) 64 (25.0)
    Tertiary 233 (46.6) 116 (47.5) 117 (45.7)
Religion


0.7
    Christianity 448 (89.6) 221 (90.6) 227 (88.7)
    Islam 49 (9.8) 22 (9.0) 27 (10.5)
    Other 3 (0.6) 1 (0.4) 2 (0.8)
Marital Status


0.7
    Currently Married 333 (66.6) 167 (68.4) 166 (64.8)
    Never Married 23 (4.6) 11 (4.5) 12 (4.7)
    Previously married 144 (28.8) 66 (27.0) 78 (30.5)
Domicile


0.8
    Rural 33 (6.6) 18 (7.4) 15 (5.9)
    Semi-Urban 166 (33.2) 80 (32.8) 86 (33.6)
    Urban 301 (60.2) 146 (59.8) 155 (60.5)
Income Bracket


>0.9
    0-100 174 (35.1) 81 (33.6) 93 (36.5)
    101-250 149 (30.0) 74 (30.7) 75 (29.4)
    251-500 109 (22.0) 54 (22.4) 55 (21.6)
    501-1500 43 (8.7) 22 (9.1) 21 (8.2)
    1501-3000 15 (3.0) 7 (2.9) 8 (3.1)
    > 3000 6 (1.2) 3 (1.2) 3 (1.2)
    Missing 4 3 1
BMI (kg/m2)- Baseline 26.4 (22.7, 30.5) 26.6 (23.1, 30.9) 26.3 (22.5, 29.7) 0.5
    Missing 71 34 37
Stroke Type (Choose One)


0.013
    Ischemic Stroke 319 (73.5) 163 (75.8) 156 (71.2)
    Intracerebral Hemorrhagic Stroke 100 (23.0) 44 (20.5) 56 (25.6)
    Ischemic With Hemorrhagic Transformation 10 (2.3) 8 (3.7) 2 (0.9)
    Untyped Stroke (no CT scan available) 5 (1.2) 0 (0.0) 5 (2.3)
    Missing 66 29 37
Modified Ranking Score 2.00 (1.00, 3.00) 2.00 (1.00, 3.00) 2.00 (1.00, 3.00) 0.9
    Missing 3 1 2
1

n (%); Median (Q1, Q3)

2

Pearson’s Chi-squared test; Fisher’s exact test; Wilcoxon rank sum test

Table 2

Show the code
tbl1 <- 
    df_table_2 %>% 
    select(ee_sbp_0, ee_sbp_3, ee_sbp_12, arm) %>% 
    gtsummary::tbl_summary(
        statistic = gtsummary::all_continuous() ~ "{mean} ({sd})",
        missing_text = "Missing", 
        by = arm,
        label = list(
            ee_sbp_0 ~ "Month 0",
            ee_sbp_3 ~ "Month 3",
            ee_sbp_12 ~ "Month 12"
            )
        ) %>% 
    gtsummary::add_overall() %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::add_p() %>% 
    gtsummary::bold_p()

#---------------------

tbl2 <- 
    df_table_2 %>% 
    mutate(
        sbp_0_cat = case_when(
            ee_sbp_0 < 140 ~ "Yes", ee_sbp_0 >= 140 ~ "No"),
        sbp_3_cat = case_when(
            ee_sbp_3 < 140 ~ "Yes", ee_sbp_3 >= 140 ~ "No"), 
        sbp_12_cat = case_when(
            ee_sbp_12 < 140 ~ "Yes", ee_sbp_12 >= 140 ~ "No")) %>% 
    select(sbp_0_cat, sbp_3_cat, sbp_12_cat, arm) %>% 
    gtsummary::tbl_summary(
        statistic = gtsummary::all_categorical() ~ "{n} ({p})",
        missing_text = "Missing", 
        by = arm,
        label = list(
            sbp_0_cat ~ "Month 0",
            sbp_3_cat ~ "Month 3",
            sbp_12_cat ~ "Month 12"
            )
        ) %>% 
    gtsummary::add_overall() %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::add_p() %>% 
    gtsummary::bold_p()

#--------------

tbl3 <- 
    df_table_2 %>% 
    mutate(
        sbp_0_cat = case_when(
            (ee_sbp_0 < 140) & (ee_dbp_0 < 90) ~ "Yes", 
            (ee_sbp_0 >= 140) | (ee_dbp_0 >= 90) ~ "No"),
        sbp_3_cat = case_when(
            (ee_sbp_3 < 140) & (ee_dbp_3 < 90) ~ "Yes", 
            (ee_sbp_3 >= 140) | (ee_dbp_3 >= 90) ~ "No"),
        sbp_12_cat = case_when(
            (ee_sbp_12 < 140) & (ee_dbp_12 < 90) ~ "Yes", 
            (ee_sbp_12 >= 140) | (ee_dbp_12 >= 90) ~ "No")
        ) %>% 
    select(sbp_0_cat, sbp_3_cat, sbp_12_cat, arm) %>% 
    gtsummary::tbl_summary(
        statistic = gtsummary::all_categorical() ~ "{n} ({p})",
        missing_text = "Missing", 
        by = arm,
        label = list(
            sbp_0_cat ~ "Month 0",
            sbp_3_cat ~ "Month 3",
            sbp_12_cat ~ "Month 12"
            )
        ) %>% 
    gtsummary::add_overall() %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::add_p() %>% 
    gtsummary::bold_p()

#---------

gtsummary::tbl_stack(
    group_header = c(
        "Systolic BP: Mean (SD)", 
        "Systolic BP <140: n (%)", 
        "Blood Pressure <140/90: n (%)"),
    tbls = list(tbl1, tbl2, tbl3),
    ) %>% 
    gtsummary::modify_caption("Table 2: Study Outcomes") 
Table 2: Study Outcomes

Characteristic

Overall
N = 500

1

Intervention
N = 244

1

Routine Care
N = 256

1

p-value

2
Systolic BP: Mean (SD)
Month 0 158 (19) 157 (18) 158 (20) 0.7
Month 3 143 (19) 142 (20) 144 (19) 0.3
    Missing 67 25 42
Month 12 141 (21) 138 (20) 143 (22) 0.003
    Missing 90 44 46
Systolic BP <140: n (%)
Month 0 41 (8.2) 22 (9.0) 19 (7.4) 0.5
Month 3 209 (48) 107 (49) 102 (48) 0.8
    Missing 67 25 42
Month 12 235 (57) 141 (71) 94 (45) <0.001
    Missing 90 44 46
Blood Pressure <140/90: n (%)
Month 0 31 (6.2) 17 (7.0) 14 (5.5) 0.5
Month 3 172 (40) 84 (39) 88 (41) 0.6
    Missing 68 26 42
Month 12 205 (50) 119 (60) 86 (41) <0.001
    Missing 90 44 46
1

Mean (SD)

2

Wilcoxon rank sum test

Table 3

Show the code
tbl2 <- 
    df_table_3_hillbone %>% 
    select(Baseline, Month12, arm) %>% 
    gtsummary::tbl_summary(
        statistic = gtsummary::all_continuous() ~ "{mean} ({sd})",
        missing_text = "Missing", 
        by = arm,
        label = list(
            Baseline ~ "Baseline",
            Month12 ~ "Month 12"
            )
        ) %>% 
    gtsummary::add_overall() %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::add_p() %>% 
    gtsummary::bold_p()

#---------------------

tbl3 <- 
    df_adverse_event %>% 
    select(gg_stroke, gg_stemi, gg_cdeath, status, arm) %>% 
    gtsummary::tbl_summary(
        statistic = gtsummary::all_continuous() ~ "{mean} ({sd})",
        missing_text = "Missing", 
        by = arm,
        label = list(
            gg_stroke ~ "Recurrent stroke",
            gg_stemi ~ "Myocardial infarction",
            gg_cdeath ~ "Vascular deaths",
            status ~ "All-cause mortality")
        ) %>% 
    gtsummary::add_overall() %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::add_p() %>% 
    gtsummary::bold_p()

#---------------------

tbl4 <- 
    df_hpt_stroke_know %>% 
    gtsummary::tbl_summary(
        statistic = gtsummary::all_continuous() ~ "{mean} ({sd})",
        missing_text = "Missing", 
        by = arm,
        label = list(
            Baseline ~ "Baseline",
            Month12 ~ "Month 12")
        ) %>% 
    gtsummary::add_overall() %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::add_p() %>% 
    gtsummary::bold_p()

#---------------
tbl5 <- 
    df_table_3_qol %>% 
    select(Baseline, Month12, arm) %>% 
    gtsummary::tbl_summary(
        statistic = gtsummary::all_continuous() ~ "{mean} ({sd})",
        missing_text = "Missing", 
        by = arm,
        label = list(
            Baseline ~ "Baseline",
            Month12 ~ "Month 12"
            )
        ) %>% 
    gtsummary::add_overall() %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::add_p() %>% 
    gtsummary::bold_p()


#---------------
tbl6 <- 
    df_ranking %>% 
    select(Baseline, Month12, arm) %>% 
    gtsummary::tbl_summary(
        statistic = gtsummary::all_continuous() ~ "{mean} ({sd})",
        missing_text = "Missing", 
        by = arm,
        label = list(
            Baseline ~ "Baseline",
            Month12 ~ "Month 12"
            ),
        type = list(
            Baseline ~ "continuous",
            Month12 ~ "continuous")
        ) %>% 
    gtsummary::add_overall() %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::add_p() %>% 
    gtsummary::bold_p()

#-----------

gtsummary::tbl_stack(
    group_header = c(
        "Medication Adherence 14-item Hill Bone Compliance", 
        "Major Adverse Cardiovascular Events over 12 months", 
        "Health Literacy in HPT/stroke",
        "Health-related quality of life",
        "Functional Status (Modified Rankin Score)"),
    tbls = list(tbl2, tbl3, tbl4, tbl5, tbl6),
    ) %>% 
    gtsummary::modify_caption("Table 3") 
Table 3

Characteristic

Overall
N = 500

1

Arm 1- Intervention Arm
N = 244

1

Arm 2- Routine Care
N = 256

1

p-value

2
Medication Adherence 14-item Hill Bone Compliance
Baseline 50.9 (4.1) 50.8 (3.8) 50.9 (4.3) 0.3
    Missing 9 3 6
Month 12 51.36 (3.30) 51.50 (2.89) 51.23 (3.66) 0.8
    Missing 82 39 43
Major Adverse Cardiovascular Events over 12 months
Recurrent stroke 7 (1.4%) 6 (2.5%) 1 (0.4%) 0.063
Myocardial infarction 1 (0.2%) 1 (0.4%) 0 (0%) 0.5
Vascular deaths 4 (0.8%) 3 (1.2%) 1 (0.4%) 0.4
All-cause mortality 13 (3.4%) 6 (3.3%) 7 (3.4%) >0.9
    Missing 113 60 53
Health Literacy in HPT/stroke
Baseline 8 (3) 8 (3) 7 (3) 0.038
    Missing 31 13 18
Month 12 10 (2) 10 (2) 9 (2) 0.087
    Missing 94 43 51
Baseline 8.38 (2.59) 8.36 (2.57) 8.40 (2.61) 0.9
    Missing 5 0 5
Month 12 6.87 (2.22) 6.84 (2.17) 6.89 (2.27) >0.9
    Missing 79 38 41
Functional Status (Modified Rankin Score)
Baseline 2.21 (1.26) 2.20 (1.25) 2.22 (1.28) 0.9
    Missing 3 1 2
Month 12 1.54 (1.34) 1.52 (1.35) 1.56 (1.33) 0.6
    Missing 66 31 35
1

Mean (SD)

2

Wilcoxon rank sum test