本部分預計時間:40 分鐘
在第二部分,你已經學會讀取資料並探索它的基本結構。現在我們要用這些資料產出論文中最重要的表格 — Table 1。
我有一個 R 資料框 patient_data(從 patient_data.csv 讀取),欄位有 treatment(A/B)、age、gender(M/F)、los(住院天數)。請幫我用 gtsummary 一次完成:
- 建立 Table 1,依 treatment 分組,連續變數顯示 mean ± SD,類別變數顯示 n (%)
- 加上 p-value(
add_p()),並解釋 gtsummary 怎麼自動選擇統計方法
- 把欄位名稱改成中文(age → 年齡、gender → 性別、los → 住院天數),p < 0.05 粗體
- 用 flextable 和 officer 把表格匯出成 Word 檔(Table1.docx)
給我一個可以從 read.csv() 到匯出 Word 一次跑完的完整 script,加上中文註解。
本書的每個章節都會重新讀取 patient_data.csv,這樣你可以從任何一個章節開始練習,不需要按順序執行前面的章節。
任務 9:Table 1 是什麼?
📋 複製這段話,貼給 AI:
在醫學論文裡面,Table 1 通常是什麼?它的目的是什麼?裡面通常會放哪些東西?
Table 1 說明
在醫學論文中,Table 1 通常是「基線特徵表」(Baseline Characteristics Table),用來:
- 展示研究對象的基本特徵
- 比較不同組別的基線資料
- 讓讀者判斷組別是否平衡
- 提供研究族群的整體概況
任務 10:你的第一個 Table 1
📋 複製這段話,貼給 AI:
我有一個 R 資料框叫做 patient_data,裡面有這些欄位:
- treatment:治療組別(A 或 B)
- age:年齡
- gender:性別(M 或 F)
- los:住院天數
請用 gtsummary 套件幫我做一個 Table 1,依照 treatment 分組,顯示其他變數的描述性統計。請給我可以直接執行的程式碼。
建立 Table 1
library(gtsummary)
library(dplyr)
# 讀取資料
patient_data <- read.csv("patient_data.csv")
# 建立基本的 Table 1
# 小提醒:%>% 是「管道」符號,把左邊的結果傳給右邊的函數
# 可以想像成工廠流水線:資料 → 選欄位 → 做摘要
table1 <- patient_data %>%
select(treatment, age, gender, los) %>%
tbl_summary(
by = treatment,
statistic = list(
all_continuous() ~ "{mean} ({sd})",
all_categorical() ~ "{n} ({p}%)"
)
)
table1
| age |
42 (4) |
56 (5) |
| gender |
|
|
| F |
23 (46%) |
27 (54%) |
| M |
27 (54%) |
23 (46%) |
| los |
5 (1) |
12 (2) |
任務 11:加上統計檢定
📋 複製這段話,貼給 AI:
剛剛的 Table 1 很棒。請幫我加上 p-value,讓我可以看出兩組之間有沒有統計顯著差異。
加入 p-value
# 建立含 p-value 的 Table 1
table1_with_p <- patient_data %>%
select(treatment, age, gender, los) %>%
tbl_summary(
by = treatment,
statistic = list(
all_continuous() ~ "{mean} ({sd})",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
add_p()
table1_with_p
| age |
42 (4) |
56 (5) |
<0.001 |
| gender |
|
|
0.4 |
| F |
23 (46%) |
27 (54%) |
|
| M |
27 (54%) |
23 (46%) |
|
| los |
5 (1) |
12 (2) |
<0.001 |
任務 12:看懂 gtsummary 的選擇
📋 複製這段話,貼給 AI:
gtsummary 在計算 p-value 的時候,是怎麼決定要用什麼統計方法的?例如,什麼時候用 t-test、什麼時候用 Wilcoxon、什麼時候用卡方檢定?
gtsummary 的統計方法選擇
gtsummary 會根據資料類型自動選擇適當的統計檢定:
- 連續變數:預設使用 Wilcoxon rank-sum test(無母數檢定)
- 類別變數:使用 Chi-square test(卡方檢定)或 Fisher’s exact test(當樣本數小時)
你可以自訂統計方法:
# 自訂統計檢定方法
table1_custom <- patient_data %>%
select(treatment, age, gender, los) %>%
tbl_summary(
by = treatment,
statistic = list(
all_continuous() ~ "{mean} ({sd})",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
add_p(
test = list(
age ~ "t.test", # 使用 t-test
los ~ "wilcox.test", # 使用 Wilcoxon test
gender ~ "chisq.test" # 使用卡方檢定
)
)
table1_custom
| age |
42 (4) |
56 (5) |
<0.001 |
| gender |
|
|
0.5 |
| F |
23 (46%) |
27 (54%) |
|
| M |
27 (54%) |
23 (46%) |
|
| los |
5 (1) |
12 (2) |
<0.001 |
任務 13:客製化你的表格
📋 複製這段話,貼給 AI:
我想要修改我的 gtsummary 表格:
- 連續變數顯示「平均值 ± 標準差」而不是中位數
- 把欄位名稱改成中文(age → 年齡、gender → 性別、los → 住院天數)
- p-value 如果小於 0.05 就用粗體標示
客製化表格
# 客製化 Table 1
table1_final <- patient_data %>%
select(treatment, age, gender, los) %>%
tbl_summary(
by = treatment,
label = list(
age ~ "年齡",
gender ~ "性別",
los ~ "住院天數"
),
statistic = list(
all_continuous() ~ "{mean} ± {sd}",
all_categorical() ~ "{n} ({p}%)"
)
) %>%
add_p() %>%
bold_p(t = 0.05) %>%
modify_header(label ~ "**變項**") %>%
modify_spanning_header(c("stat_1", "stat_2") ~ "**治療組別**")
table1_final
A
N = 50 |
B
N = 50 |
| 年齡 |
42 ± 4 |
56 ± 5 |
<0.001 |
| 性別 |
|
|
0.4 |
| F |
23 (46%) |
27 (54%) |
|
| M |
27 (54%) |
23 (46%) |
|
| 住院天數 |
5 ± 1 |
12 ± 2 |
<0.001 |
任務 14:匯出你的表格
📋 複製這段話,貼給 AI:
我做好了一個 gtsummary 的表格,想存在變數 table1_final 裡面。我想要用 flextable 和 officer 把它輸出成 Word 跟 PPT 檔案,方便貼到我的論文。請給我程式碼。
匯出表格
# 安裝必要套件(如果還沒安裝)
# install.packages(c("flextable", "officer"))
library(flextable)
library(officer)
# 儲存表格為變數
my_table <- table1_final
# 轉換為 flextable 格式
ft <- my_table %>% as_flex_table()
# 存成 Word 檔
doc <- read_docx() %>%
body_add_flextable(ft)
print(doc, target = "Table1.docx")
# 存成 PPT 檔
ppt <- read_pptx() %>%
add_slide(layout = "Title and Content", master = "Office Theme") %>%
ph_with(ft, location = ph_location_type(type = "body"))
print(ppt, target = "Table1.pptx")
print("Table 1 已成功匯出為 Table1.docx 和 Table1.pptx")