Cath Lab Data Analysis

Author

Dr Samuel Blay Nguah

Published

April 19, 2024

Anlysis format
  1. Demographic characteristics of participants
    • Sex,
    • Age,
    • Marital status
    • Nationality
    • Ethnicity
    • Race
    • Religion
    • Occupation
  2. Type of procedures
    • Which variable in the excel sheet determines this?
  3. Prevalence of CVD risk factors
    • Hypertension
    • DM
    • Dyslipidaemia
    • Smoking
    • Old age >/=60 yrs.
  4. Let’s also look at proportion with multiple risk factors (1, 2, or 3 RF)
  5. Types of coronary lesions (normal, single vessel, 2 vessel or 3 vessel disease)
    • Which variables determines this in the excel sheet.
  6. Coronary disease severity by risk level (no, one, two, three or more)
    • Which variable in the excel sheet determines this?
  7. Outcomes of PCI (emergency vs. elective)
    • Which variable determines this
  8. What is or are the outcome variables?
  9. Mode of presentation(ACS vrs CCS)

Table 1: Demographics

Code
gtsummary::theme_gtsummary_compact()
Setting theme `Compact`
Code
table_1 <- 
    df_cathlab %>% 
    select(
        sex, age, marital_status, nationality,ethnicity, race, religion, 
        occupation
        ) %>% 
    gtsummary::tbl_summary(
        by = sex,
        digits = gtsummary::all_categorical()~ c(0, 1),
        statistic = gtsummary::all_categorical() ~ "{n}({p})",
        sort = list(everything() ~ "frequency"),
        missing = "no"
        ) %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::modify_spanning_header(
        gtsummary::all_stat_cols() ~ "**Sex**"
        ) %>% 
    gtsummary::add_overall(last = T) %>% 
    gtsummary::modify_caption(
        caption = "**Table 1**: Demographic Charateristics of patients"
        ) 

table_1 
Table 1: Demographic Charateristics of patients
Characteristic Sex Overall, N = 4631
Female, N = 1111 Male, N = 3521
Age (years) 64 (53, 71) 59 (52, 66) 60 (52, 67)
Marital Status


    Married 63(66.3) 296(92.2) 359(86.3)
    Single 16(16.8) 18(5.6) 34(8.2)
    Widowed 12(12.6) 2(0.6) 14(3.4)
    Divorced 4(4.2) 5(1.6) 9(2.2)
Nationaliity


    Ghanaian 106(95.5) 307(87.2) 413(89.2)
    Non-Ghanaian 5(4.5) 45(12.8) 50(10.8)
Ethnicity


    Akan 47(43.9) 154(45.6) 201(45.2)
    Others 18(16.8) 90(26.6) 108(24.3)
    Ewe 23(21.5) 48(14.2) 71(16.0)
    Ga-Adangbe 19(17.8) 46(13.6) 65(14.6)
Race


    African 109(99.1) 331(95.7) 440(96.5)
    Others 1(0.9) 15(4.3) 16(3.5)
Religion


    Christian 103(95.4) 296(87.1) 399(89.1)
    Islamic 5(4.6) 36(10.6) 41(9.2)
    Others 0(0.0) 8(2.4) 8(1.8)
Occupation


    Public Sector 26(24.1) 104(29.9) 130(28.5)
    Retired 40(37.0) 77(22.1) 117(25.7)
    Self-employed 24(22.2) 77(22.1) 101(22.1)
    Private Sector 7(6.5) 89(25.6) 96(21.1)
    Unemployed 11(10.2) 1(0.3) 12(2.6)
1 Median (IQR); n(%)
Code
file.remove("table_1.docx")
[1] TRUE
Code
table_1 %>% 
    gtsummary::as_gt() %>% 
    gt::gtsave(filename = "table_1.docx")

Table 2: Clinicals

Code
table_2 <- 
    df_cathlab %>% 
    select(
        sex, presentation, urgency_of_procedure, type_of_intervention, 
        procedure, risk_factors_cat, type_of_lesion, urgency_of_procedure, 
        number_of_stents, in_hospital_outcome
        ) %>% 
    gtsummary::tbl_summary(
        by = sex,
        type = list(number_of_stents ~ "continuous"),
        digits = list(
            gtsummary::all_categorical()~ c(0, 1),
            number_of_stents ~ 0),
        statistic = gtsummary::all_categorical() ~ "{n}({p})",
        sort = list(c(
            in_hospital_outcome, urgency_of_procedure, 
            presentation) ~ "frequency"),
        missing = "no"
        ) %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::modify_spanning_header(
        gtsummary::all_stat_cols() ~ "**Sex**"
        ) %>% 
    gtsummary::modify_caption(
        caption = "**Table 2**: Clinical Charateristics of patients"
        ) %>% 
    gtsummary::add_overall(last = T)

table_2 
Table 2: Clinical Charateristics of patients
Characteristic Sex Overall, N = 4631
Female, N = 1111 Male, N = 3521
Presentation


    CCS 85(76.6) 249(70.7) 334(72.1)
    ACS 16(14.4) 67(19.0) 83(17.9)
    Heart Failure 7(6.3) 33(9.4) 40(8.6)
    Pre-op 3(2.7) 2(0.6) 5(1.1)
    VHD 0(0.0) 1(0.3) 1(0.2)
Urgency of procedure


    Elective 98(88.3) 289(82.1) 387(83.6)
    Emergency 13(11.7) 63(17.9) 76(16.4)
Type of intervention


    CABG 4(5.5) 22(8.6) 26(7.9)
    OMT 31(42.5) 99(38.5) 130(39.4)
    PCI 37(50.7) 134(52.1) 171(51.8)
    POBA 1(1.4) 2(0.8) 3(0.9)
Procedure


    CAG 74(66.7) 219(62.2) 293(63.3)
    PCI 37(33.3) 133(37.8) 170(36.7)
No. of Risk factors


    None 2(1.8) 15(4.3) 17(3.7)
    1 to 3 74(66.7) 222(63.1) 296(63.9)
    4 to 7 35(31.5) 115(32.7) 150(32.4)
Type of Coronary Lesion


    Normal 36(32.4) 91(25.9) 127(27.5)
    MNOD 22(19.8) 52(14.8) 74(16.0)
    1VD 25(22.5) 65(18.5) 90(19.5)
    2VD 15(13.5) 55(15.7) 70(15.2)
    3VD 8(7.2) 62(17.7) 70(15.2)
    LMD 5(4.5) 26(7.4) 31(6.7)
Number of Stents 1 (1, 2) 2 (1, 2) 2 (1, 2)
In-hospital Outcome


    Discharged 110(99.1) 345(98.6) 455(98.7)
    Died 1(0.9) 5(1.4) 6(1.3)
1 n(%); Median (IQR)
Code
file.remove("table_2.docx")
[1] TRUE
Code
table_2 %>% 
    gtsummary::as_gt() %>% 
    gt::gtsave(filename = "table_2.docx")

Table 3: Clinicals

Code
table_3 <- 
    df_cathlab %>% 
    select(agecat, presentation,urgency_of_procedure, procedure, risk_factors_cat, 
           type_of_lesion, risk_factors_cat, in_hospital_outcome, 
           urgency_of_procedure, type_of_intervention, 
           number_of_stents) %>% 
    gtsummary::tbl_summary(
        by = agecat,
        type = list(number_of_stents ~ "continuous"),
        digits = list(
            gtsummary::all_categorical()~ c(0, 1),
            number_of_stents ~ 0),
        statistic = gtsummary::all_categorical() ~ "{n}({p})",
        sort = list(c(in_hospital_outcome, urgency_of_procedure, 
                      presentation) ~ "frequency"),
        missing = "no"
        ) %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::modify_spanning_header(
        gtsummary::all_stat_cols() ~ "**Age in years**"
        ) %>% 
    gtsummary::modify_caption(
        caption = "**Table 3**: Clinical Charateristics of patients"
        ) %>% 
    gtsummary::add_overall(last = T)
17 observations missing `agecat` have been removed. To include these observations, use `forcats::fct_na_value_to_level()` on `agecat` column before passing to `tbl_summary()`.
Code
table_3 
Table 3: Clinical Charateristics of patients
Characteristic Age in years Overall, N = 4461
<45 years, N = 431 45 to 65 years, N = 2731 >65 years, N = 1301
Presentation



    CCS 30(69.8) 195(71.4) 96(73.8) 321(72.0)
    ACS 8(18.6) 50(18.3) 22(16.9) 80(17.9)
    Heart Failure 5(11.6) 26(9.5) 8(6.2) 39(8.7)
    Pre-op 0(0.0) 2(0.7) 3(2.3) 5(1.1)
    VHD 0(0.0) 0(0.0) 1(0.8) 1(0.2)
Urgency of procedure



    Elective 37(86.0) 224(82.1) 112(86.2) 373(83.6)
    Emergency 6(14.0) 49(17.9) 18(13.8) 73(16.4)
Procedure



    CAG 30(69.8) 165(60.4) 89(68.5) 284(63.7)
    PCI 13(30.2) 108(39.6) 41(31.5) 162(36.3)
No. of Risk factors



    None 9(20.9) 8(2.9) 0(0.0) 17(3.8)
    1 to 3 31(72.1) 188(68.9) 69(53.1) 288(64.6)
    4 to 7 3(7.0) 77(28.2) 61(46.9) 141(31.6)
Type of Coronary Lesion



    Normal 22(51.2) 72(26.5) 30(23.1) 124(27.9)
    MNOD 6(14.0) 30(11.0) 33(25.4) 69(15.5)
    1VD 9(20.9) 63(23.2) 16(12.3) 88(19.8)
    2VD 2(4.7) 52(19.1) 14(10.8) 68(15.3)
    3VD 3(7.0) 36(13.2) 27(20.8) 66(14.8)
    LMD 1(2.3) 19(7.0) 10(7.7) 30(6.7)
In-hospital Outcome



    Discharged 42(97.7) 267(98.2) 129(100.0) 438(98.6)
    Died 1(2.3) 5(1.8) 0(0.0) 6(1.4)
Type of intervention



    CABG 1(4.8) 15(7.6) 10(10.1) 26(8.2)
    OMT 7(33.3) 71(36.0) 47(47.5) 125(39.4)
    PCI 12(57.1) 109(55.3) 42(42.4) 163(51.4)
    POBA 1(4.8) 2(1.0) 0(0.0) 3(0.9)
Number of Stents 2 (1, 2) 2 (1, 2) 2 (1, 3) 2 (1, 2)
1 n(%); Median (IQR)
Code
file.remove("table_3.docx")
[1] TRUE
Code
table_3 %>% 
    gtsummary::as_gt() %>% 
    gt::gtsave(filename = "table_3.docx")

Table 4

Code
table_4 <- 
    df_cathlab %>% 
    select(type_of_lesion, risk_factors_cat, ethnicity) %>% 
    gtsummary::tbl_summary(
        by = type_of_lesion,
        digits = gtsummary::all_categorical()~ c(0, 1),
        statistic = gtsummary::all_categorical() ~ "{n}({p})",
        sort = list(gtsummary::everything() ~ "frequency"),
        missing = "no"
        ) %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::modify_spanning_header(
        gtsummary::all_stat_cols() ~ "**Lesion Type**"
        ) %>% 
    gtsummary::modify_caption(
        caption = "**Table 3**"
        ) %>% 
    gtsummary::add_overall(last = T)
1 observations missing `type_of_lesion` have been removed. To include these observations, use `forcats::fct_na_value_to_level()` on `type_of_lesion` column before passing to `tbl_summary()`.
Code
table_4
Table 3
Characteristic Lesion Type Overall, N = 4621
Normal, N = 1271 MNOD, N = 741 1VD, N = 901 2VD, N = 701 3VD, N = 701 LMD, N = 311
No. of Risk factors






    1 to 3 76(59.8) 47(63.5) 69(76.7) 45(64.3) 39(55.7) 20(64.5) 296(64.1)
    4 to 7 41(32.3) 26(35.1) 17(18.9) 24(34.3) 31(44.3) 10(32.3) 149(32.3)
    None 10(7.9) 1(1.4) 4(4.4) 1(1.4) 0(0.0) 1(3.2) 17(3.7)
Ethnicity






    Akan 58(46.0) 41(57.7) 40(47.1) 20(30.8) 29(43.3) 12(40.0) 200(45.0)
    Others 25(19.8) 17(23.9) 24(28.2) 20(30.8) 13(19.4) 9(30.0) 108(24.3)
    Ewe 26(20.6) 4(5.6) 14(16.5) 15(23.1) 11(16.4) 1(3.3) 71(16.0)
    Ga-Adangbe 17(13.5) 9(12.7) 7(8.2) 10(15.4) 14(20.9) 8(26.7) 65(14.6)
1 n(%)
Code
file.remove("table_4.docx")
[1] TRUE
Code
table_4 %>% 
    gtsummary::as_gt() %>% 
    gt::gtsave(filename = "table_4.docx")

Table 5

Code
table_5 <- 
    df_cathlab %>% 
    gtsummary::tbl_cross(
        row = urgency_of_procedure, 
        col = in_hospital_outcome,percent = "row",
        missing = "no") %>% 
    gtsummary::add_p() %>% 
    gtsummary::bold_labels()
FALSE observations with missing data have been removed.
Code
table_5 
In-hospital Outcome Total p-value1
Died Discharged
Urgency of procedure


<0.001
    Elective 1 (0.3%) 384 (100%) 385 (100%)
    Emergency 5 (6.6%) 71 (93%) 76 (100%)
Total 6 (1.3%) 455 (99%) 461 (100%)
1 Fisher’s exact test
Code
file.remove("table_5.docx")
[1] TRUE
Code
table_5 %>% 
    gtsummary::as_gt() %>% 
    gt::gtsave(filename = "table_5.docx")

Graph of risk factors by sex

Code
df_temp <- 
    df_cathlab %>% 
    select(
        sex, hpn, t2dm, dyslip, prev_cad, smoking, obesity, alcohol, f_hx_cad, 
        phy_inactivity, old_age
        ) %>% 
    pivot_longer(cols = hpn:old_age) %>% 
    group_by(sex, name) %>% 
    count(value) %>% 
    pivot_wider(names_from = value, values_from = n) %>%  
    mutate(total = No + Yes)

df_temp2 <- 
    epiDisplay::ci.binomial(df_temp$Yes, df_temp$total) %>% 
    select(-total) %>% 
    cbind(df_temp) %>% 
    select(name, sex, events, total, probability, se, exact.lower95ci, exact.upper95ci) %>% 
    arrange(name, sex) %>% 
    mutate(
        name = case_when(
            name == "t2dm" ~ "Type II DM",
            name == "smoking" ~ "Smoking",
            name == "prev_cad" ~ "Previous CAD",
            name == "phy_inactivity" ~"Physical Inactivity",
            name == "old_age" ~ "Age >= 60 years",
            name == "dyslip" ~ "Dyslipidemia",
            name == "f_hx_cad" ~ "Family History of CAD",
            name == "alcohol" ~ "Alcohol use",
            name == "hpn" ~ "Hypertension",
            name == "obesity" ~ "Obesity",
            TRUE ~ name
            ) %>% factor(
                levels = c(
                    "Hypertension","Age >= 60 years", "Dyslipidemia", "Type II DM", 
                    "Obesity", "Previous CAD", "Physical Inactivity", "Alcohol use", 
                    "Family History of CAD", "Smoking")
                )
        )

df_temp2 %>% 
    mutate(across(probability:exact.upper95ci, ~round(.x*100, 1))) %>% 
    rename(
        "Prob" = "probability", 
        `Lower 95% CI` = exact.lower95ci,
        `Upper 95% CI` = exact.upper95ci) %>% 
    select(-c(events, total, se)) %>% 
    flextable::as_flextable() %>% 
    flextable::theme_vanilla() %>% 
    flextable::save_as_docx(path = "Table_for_Graph.docx")

df_temp2 %>% 
    ggplot(aes(y = probability, fill = sex, x = name)) +
    geom_bar(stat = "identity", position = position_dodge()) +
    geom_errorbar(
        aes(ymin = exact.lower95ci, ymax = exact.upper95ci),
        position = position_dodge(0.9),
        width = 0.25,
        linewidth = 0.2) +
    labs(fill = "Sex of Patient", y = "Proportion", x = NULL) +
    coord_flip() +
    theme_light() +
    theme(legend.position = "top")+
    scale_fill_brewer(palette = "Pastel1") +
    scale_y_continuous(limits = c(0, 1))

Code
 ggsave(filename = "Figure_1.jpg", width = 7, height = 5)

Table 6: Clinicals

Code
table_6 <- 
    df_cathlab %>% 
    select(risk_factors_cat, type_of_lesion, ethnicity) %>% 
    gtsummary::tbl_summary(
        by = ethnicity,
        digits = list(gtsummary::all_categorical()~ c(0, 1)),
        statistic = gtsummary::all_categorical() ~ "{n}({p})",
        missing = "no"
        ) %>% 
    gtsummary::bold_labels() %>% 
    gtsummary::modify_spanning_header(
        gtsummary::all_stat_cols() ~ "**Ethnicity**"
        ) %>% 
    gtsummary::modify_caption(
        caption = "**Table 6**: Clinical Charateristics of patients"
        ) %>% 
    gtsummary::add_overall(last = T)
18 observations missing `ethnicity` have been removed. To include these observations, use `forcats::fct_na_value_to_level()` on `ethnicity` column before passing to `tbl_summary()`.
Code
table_6 
Table 6: Clinical Charateristics of patients
Characteristic Ethnicity Overall, N = 4451
Akan, N = 2011 Ewe, N = 711 Ga-Adangbe, N = 651 Others, N = 1081
No. of Risk factors




    None 5(2.5) 2(2.8) 3(4.6) 6(5.6) 16(3.6)
    1 to 3 124(61.7) 44(62.0) 41(63.1) 73(67.6) 282(63.4)
    4 to 7 72(35.8) 25(35.2) 21(32.3) 29(26.9) 147(33.0)
Type of Coronary Lesion




    Normal 58(29.0) 26(36.6) 17(26.2) 25(23.1) 126(28.4)
    MNOD 41(20.5) 4(5.6) 9(13.8) 17(15.7) 71(16.0)
    1VD 40(20.0) 14(19.7) 7(10.8) 24(22.2) 85(19.1)
    2VD 20(10.0) 15(21.1) 10(15.4) 20(18.5) 65(14.6)
    3VD 29(14.5) 11(15.5) 14(21.5) 13(12.0) 67(15.1)
    LMD 12(6.0) 1(1.4) 8(12.3) 9(8.3) 30(6.8)
1 n(%)
Code
file.remove("table_6.docx")
[1] TRUE
Code
table_6 %>% 
    gtsummary::as_gt() %>% 
    gt::gtsave(filename = "table_6.docx")

Saving data

Code
write_rds(x = df_cathlab, file = "cath_lab_data.rds")