Nạp thư viện

library(readxl)
library(dplyr)
library(stringr)
library(gtsummary)
library(rstatix)
library(gtsummary)
library(ggplot2)
library(extrafont)

Nhập dữ liệu

library(readxl)

df <- read_excel("data1.xlsx", sheet=1, na=".")

Chuẩn bị biến

#Tạo biến early neuro deriotation
df <- df %>%
  mutate(
    early_neuro_deriotation = if_else(
      NIHSS_24_48h - NIHSS_score_in >= 4,1,0
    )
  ) %>%
  mutate(T6 = T1+T3) #Tạo biến onset - puncture

#Tạo biến phân nhóm có biến chứng
df <- df %>%
  mutate(phan_loai_complication = case_when(
    BCh_xuat_huyet_noi_so_3 == 1 | 
      Ctscan2_xhns3_trieuchung == 1 |
      nhoi_mau_ac_tinh == 1 |
      early_neuro_deriotation == 1 ~1,
    TRUE ~ 0
  ))
my_iqr <- function(x) {
  quantile(x, 0.75, na.rm = TRUE) - quantile(x, 0.25, na.rm = TRUE)
}

#Thực hiện bảng 1

bang1_PL_vars <- c("gioi",
                   "TS_tha",
                   "TS_dai_thao_duong",
                   "TS_rllp",
                   "TS_rung_nhi",
                   "TS_hut_thuoc",
                   "TS_dot_quy")
bang1_LT_vars <- c("tuoi",
                   "NIHSS_score_in",
                   "CLS_hatthu",
                   "HS_glc_mg_dL",
                   "T1",
                   "T6")

bang1 <- df %>%
  select(phan_loai_complication, all_of(bang1_PL_vars),all_of(bang1_LT_vars)) %>%
  tbl_summary(
    by = phan_loai_complication,
    type = list(
      all_of(bang1_LT_vars) ~ "continuous",
      all_of(bang1_PL_vars) ~ "dichotomous"
    ),
    statistic = list(
      all_continuous() ~ "{median} ({my_iqr})",
      all_dichotomous() ~ "{n} ({p}%)"
    ),
    digits = list(
      tuoi ~ 0,
      NIHSS_score_in ~0,
      CLS_hatthu ~ 0,
      HS_glc_mg_dL ~ 2,
      T1 ~ 0,
      T6 ~ 0,
      all_dichotomous() ~ 0
    ),
    missing = "no"
  ) %>%
  add_overall(
    last = FALSE,
    col_label = "**Chung**<br>(n={N})"
  ) %>%
  add_p(
    list(
      all_continuous() ~ "wilcox.test",
      all_categorical() ~ "fisher.test"),
    test.args = list(
      all_continuous() ~ list(exact = FALSE))
  ) %>%
  modify_header(
    label ~ "**Đặc điểm**",
    p.value ~ "**p**"
  ) %>%
  bold_labels()

bang1
Đặc điểm Chung
(n=80)
1
0
N = 52
1
1
N = 28
1
p2
gioi 53 (66%) 33 (63%) 20 (71%) 0.6
TS_tha 50 (63%) 29 (56%) 21 (75%) 0.15
TS_dai_thao_duong 28 (35%) 18 (35%) 10 (36%) >0.9
TS_rllp 34 (43%) 21 (40%) 13 (46%) 0.6
TS_rung_nhi 19 (24%) 11 (21%) 8 (29%) 0.6
TS_hut_thuoc 29 (36%) 18 (35%) 11 (39%) 0.8
TS_dot_quy 18 (23%) 11 (21%) 7 (25%) 0.8
tuoi 64 (18) 62 (13) 72 (16) 0.015
NIHSS_score_in 14 (5) 12 (5) 16 (5) 0.005
CLS_hatthu 140 (25) 139 (24) 140 (30) 0.4
HS_glc_mg_dL 126.18 (47.61) 126.90 (44.15) 120.24 (66.96) 0.9
T1 427 (180) 424 (168) 440 (194) 0.9
T6 548 (190) 548 (173) 548 (184) 0.8
1 n (%); Median (my_iqr)
2 Fisher’s exact test; Wilcoxon rank sum test

#Table 2

#Tạo biến phân loại điểm ASPECTS
df <- df %>%
  mutate(aspects_group = case_when(
    aspect_score >=5 & aspect_score <= 7 ~ 0,
    aspect_score >=8 & aspect_score <= 10 ~ 1
  )) %>%
  mutate(collateral_group = case_when(
    delta_collateral >=1 ~ 1,
    TRUE ~ 0
  )) #Tạo biến phân loại điểm delta collateral
#Tạo biến phân loại nhóm dual phase cta
df <- df %>%
  mutate(cta_p2_group = case_when(
    THBH_cta_p2 == 1 ~ 1,
    THBH_cta_p2 == 2 ~ 2,
    THBH_cta_p2 == 3 ~ 3
  ))

bang2_PL_vars <- c(
  "CT_tang_dom_do_mca",
  "CT_khac_biet_greywhite",
  "CT_mat_ruy_bang",
  "CT_mo_hach_nen",
  "coves_danh_gia",
  "collateral_group"
)

bang2_LT_vars <- c(
  "aspect_score",
  "cbs_score",
  "THBH_tan_p1",
  "THBH_cta_p2",
  "coves_score"
)

bang2_CAT_vars <- c(
  "aspects_group",
  "occlusion",
  "THBH_tan_danh_gia",
  "cta_p2_group"
)

bang2 <- df %>%
  select(phan_loai_complication, all_of(bang2_PL_vars),all_of(bang2_LT_vars),all_of(bang2_CAT_vars)) %>%
  tbl_summary(
    by = phan_loai_complication,
    type = list(
      all_of(bang2_LT_vars) ~ "continuous",
      all_of(bang2_PL_vars) ~ "dichotomous",
      all_of(bang2_CAT_vars) ~ "categorical"
    ),
    statistic = list(
      all_continuous() ~ "{median} ({my_iqr})",
      all_dichotomous() ~ "{n} ({p}%)",
      all_categorical() ~ "{n} ({p}%)"
    ),
    digits = list(
      all_continuous() ~ 0,
      all_dichotomous() ~ 0,
      all_categorical() ~ 0
    ),
    missing = "no"
  ) %>%
  add_overall(
    last = FALSE,
    col_label = "**Chung**<br>(n={N})"
  ) %>%
  add_p(
    list(
      all_continuous() ~ "wilcox.test",
      all_categorical() ~ "fisher.test",
      all_dichotomous() ~ "fisher.test"),
    test.args = list(
      all_continuous() ~ list(exact = FALSE))
  ) %>%
  modify_header(
    label ~ "**Đặc điểm**",
    p.value ~ "**p**"
  ) %>%
  bold_labels()

bang2
Đặc điểm Chung
(n=80)
1
0
N = 52
1
1
N = 28
1
p2
CT_tang_dom_do_mca 4 (5%) 4 (8%) 0 (0%) 0.3
CT_khac_biet_greywhite 40 (50%) 22 (42%) 18 (64%) 0.10
CT_mat_ruy_bang 29 (36%) 12 (23%) 17 (61%) 0.001
CT_mo_hach_nen 56 (70%) 32 (62%) 24 (86%) 0.039
coves_danh_gia 40 (50%) 33 (63%) 7 (25%) 0.002
collateral_group 56 (70%) 34 (65%) 22 (79%) 0.3
aspect_score 8 (2) 8 (1) 7 (1) <0.001
cbs_score 7 (2) 8 (1) 6 (2) <0.001
THBH_tan_p1 2 (1) 2 (0) 1 (2) <0.001
THBH_cta_p2 3 (1) 3 (1) 2 (1) <0.001
coves_score 3 (3) 3 (2) 1 (2) 0.001
aspects_group


<0.001
    0 35 (44%) 12 (23%) 23 (82%)
    1 45 (56%) 40 (77%) 5 (18%)
occlusion


0.4
    0 18 (23%) 13 (25%) 5 (18%)
    1 43 (54%) 29 (56%) 14 (50%)
    3 19 (24%) 10 (19%) 9 (32%)
THBH_tan_danh_gia


<0.001
    0 30 (38%) 12 (23%) 18 (64%)
    1 50 (63%) 40 (77%) 10 (36%)
cta_p2_group


0.002
    1 5 (6%) 2 (4%) 3 (11%)
    2 29 (36%) 13 (25%) 16 (57%)
    3 46 (58%) 37 (71%) 9 (32%)
1 n (%); Median (my_iqr)
2 Fisher’s exact test; Wilcoxon rank sum test

#Table 3

#Tạo biến phân loại CTA
df <- df %>%
  mutate(phan_loai_cta_p2 = case_when(
    THBH_cta_p2 == 1 | THBH_cta_p2 == 2 ~ 0,
    THBH_cta_p2 == 3 ~ 1
  )) %>%
  mutate(TICI_danh_gia = case_when(
    TICI_danh_gia == 0 ~ 1,
    TICI_danh_gia == 1 ~ 0
  ))


bang3_PL_vars<- c(
  "CTh_phuong_phap_hep_mach",
  "TICI_danh_gia", 
  "phan_loai_complication",
  "BCh_xuat_huyet_noi_so_3",
  "Ctscan2_xhns3_trieuchung",
  "nhoi_mau_ac_tinh",
  "early_neuro_deriotation",
  "tu_vong_noi_vien"
)
 bang3_LT_vars <- c(
   "CTh_so_lan_lay_huyet_khoi",
   "T6",
   "T4"
 )

 bang3 <- df %>%
   select(phan_loai_cta_p2, all_of(bang3_PL_vars),all_of(bang3_LT_vars)) %>%
   tbl_summary(
     by = phan_loai_cta_p2,
     type = list(
       all_of(bang3_LT_vars) ~ "continuous",
       all_of(bang3_PL_vars) ~ "dichotomous"
     ),
     statistic = list(
       all_continuous() ~ "{median} ({my_iqr})",
       all_dichotomous() ~ "{n} ({p}%)"
     ),
     value = list(CTh_phuong_phap_hep_mach ~ 3),
     digits = list(
       all_continuous() ~ 0,
       all_dichotomous() ~ 0
     ),
     missing = "no"
   ) %>%
   add_overall(
     last = FALSE,
     col_label = "**Chung**<br>(n={N})"
   ) %>%
   add_p(
     list(
       all_continuous() ~ "wilcox.test",
       all_dichotomous() ~ "fisher.test"),
     test.args = list(
       all_continuous() ~ list(exact = FALSE))
   ) %>%
   modify_header(
     label ~ "**Đặc điểm**",
     p.value ~ "**p**"
   ) %>%
   bold_labels()
 
 bang3
Đặc điểm Chung
(n=80)
1
0
N = 34
1
1
N = 46
1
p2
CTh_phuong_phap_hep_mach 14 (32%) 7 (35%) 7 (29%) 0.8
TICI_danh_gia 74 (93%) 31 (91%) 43 (93%) 0.7
phan_loai_complication 28 (35%) 19 (56%) 9 (20%) <0.001
BCh_xuat_huyet_noi_so_3 20 (25%) 12 (35%) 8 (17%) 0.12
Ctscan2_xhns3_trieuchung 10 (13%) 6 (18%) 4 (9%) 0.3
nhoi_mau_ac_tinh 8 (10%) 7 (21%) 1 (2%) 0.009
early_neuro_deriotation 16 (20%) 14 (41%) 2 (4%) <0.001
tu_vong_noi_vien 11 (14%) 10 (29%) 1 (2%) <0.001
CTh_so_lan_lay_huyet_khoi 2 (1) 2 (1) 2 (1) 0.5
T6 548 (190) 548 (195) 548 (182) 0.8
T4 31 (31) 37 (27) 25 (28) 0.12
1 n (%); Median (my_iqr)
2 Fisher’s exact test; Wilcoxon rank sum test
plot_data <- df %>%
  filter(!is.na(cta_p2_group), !is.na(phan_loai_complication)) %>%
  group_by(cta_p2_group) %>%
  summarise(
    total = n(),
    complication = sum(phan_loai_complication == 1),
    rate = complication / total * 100
  ) %>%
  ungroup()

plot_data <- plot_data %>%
  mutate(
    cta_label = factor(
      cta_p2_group,
      levels = c(3, 2, 1),
      labels = c(
        "Good early\nfilling",
        "Delayed\nfilling",
        "Persistent poor\nfilling"
      )
    )
  )

ggplot(plot_data, aes(x = cta_label, y = rate)) +
  geom_col(width = 0.8, fill = "#1f77b4", color = "black") +
  geom_text(
    aes(label = paste0(round(rate, 1), "%")),
    vjust = -0.5,
    size = 5
  ) +
  labs(
    title = "Complication rate by dual-phase CTA filling pattern",
    x = "Dual-phase CTA filling pattern",
    y = "Reperfusion-related complication rate (%)"
  ) +
  scale_y_continuous(
    limits = c(0, max(plot_data$rate) + 10),
    breaks = seq(0, 80, 20),
    minor_breaks = seq(0, 80, 10)
  ) +
  theme_classic(base_size = 14) +
  theme(
    text = element_text(family = "Times New Roman"),
    plot.title = element_text(
      hjust = 0.5,
      size = 18
    ),
    panel.grid.major.y = element_line(
      color = "grey85",
      linewidth = 0.4
    ),
    panel.grid.minor.y = element_line(
      color = "grey92",
      linewidth = 0.3
    ),
    panel.grid.major.x = element_blank(),
    panel.grid.minor.x = element_blank()
  )