Tuyến Trần, MD
Lập trình & Phân tích

Lộ trình tự học R cho bác sĩ: từ 0 đến chạy phân tích cho paper trong 8 tuần

8 tuần, 30 phút mỗi ngày. Lộ trình đưa một bác sĩ đi từ con số 0 đến chạy logistic regression cho một nghiên cứu đoàn hệ thật.

Bài này là lộ trình 8 tuần mình đã dùng hướng dẫn một bác sĩ đi từ chưa bao giờ mở RStudio đến chạy logistic regression cho một nghiên cứu đoàn hệ thật. Học song song trực gác, mỗi ngày 30 phút. Sau 8 tuần, paper Methods chạy hoàn toàn bằng R, table và hình đạt chuẩn xuất bản dán thẳng vào Word.

Lộ trình này không phải Tidyverse 400-page textbook. Không phải data science from scratch. Đây là lộ trình tối thiểu để 1 bác sĩ lâm sàng dùng R cho paper đầu tay trong 2 tháng.

Trước khi bắt đầu: 3 câu hỏi

Đầu tư 30 giờ chỉ có ROI nếu bạn thực sự cần R. Trả lời thật:

  1. Bạn có 1 dataset thật trong tay (paper đang viết, IRB đã pass) trong 8 tuần tới không?
  2. Bạn publish trên 2 paper/năm không?
  3. Có một trong các yếu tố: cohort prospective, MA, multi-center, reviewer chê figure?

Trả lời No cho cả 3 câu, đừng bắt đầu. Đọc trước bài so sánh khi nào SPSS đủ và khi nào nên đổi sang R để xác nhận.

Trả lời Yes ít nhất 1 câu, đặc biệt câu 1, vào lộ trình.

Tuần 1: Setup + import dữ liệu thật

Mục tiêu: Cài R + RStudio, load data của bạn vào R, xem được số dòng cột.

Cài đặt (1 buổi 30 phút):

  • Tải R từ cran.r-project.org
  • Tải RStudio Desktop free từ posit.co
  • Cài hai cái theo thứ tự (R trước, RStudio sau)
  • Mở RStudio, làm quen 4 panel: Source, Console, Environment, Files

Import dataset thật (4 buổi 30 phút):

Lấy data paper đang viết hoặc 1 paper đã publish của bạn. Mở Excel, đổi header tiếng Việt sang không dấu (Tuoi, Gioi, Outcome), unmerge cell, save. Đây là bước chuẩn bị 5 phút tiết kiệm 1 giờ gỡ lỗi.

data <- read.csv("cohort.csv")
head(data)
str(data)
nrow(data)
ncol(data)

5 lệnh trên đủ cho tuần 1. Hết tuần 1, bạn biết: nạp CSV, xem 6 dòng đầu, xem kiểu dữ liệu mỗi cột, đếm dòng cột.

Sai lầm phổ biến tuần 1: học theo dataset mtcars hoặc iris. Không nên. R chỉ bám lại nếu bạn dùng cho dự án thật ngay từ tuần 1. Đã viết kỹ trong bài về 3 thao tác R đầu tiên.

Tuần 2: Thống kê mô tả (Bảng 1)

Mục tiêu: Tạo Bảng 1 (thống kê mô tả theo nhóm) cho paper.

Lệnh cốt lõi:

summary(data)
table(data$gender)
prop.table(table(data$gender)) * 100
mean(data$age, na.rm = TRUE)
median(data$age, na.rm = TRUE)
quantile(data$age, na.rm = TRUE)

Bảng 1 publication-ready:

library(gtsummary)
data %>%
 tbl_summary(by = outcome,
 statistic = list(all_continuous() ~ "{median} ({p25}, {p75})",
 all_categorical() ~ "{n} ({p}%)")) %>%
 add_p()

Đoạn gtsummary này là "bí kíp" tuần 2. Tôi dùng đúng đoạn cho Bảng 1 của một paper retrospective; reviewer không hỏi gì về format Bảng 1.

Kết quả tuần 2: 1 file Rmd (hoặc R script) tạo được Bảng 1 từ dữ liệu thật của bạn. Dán vào Word, sửa đôi chỗ, dùng được luôn cho bản nháp Methods.

Tuần 3: So sánh hai nhóm

Mục tiêu: t-test, Mann-Whitney, chi-square cho paper.

Quy trình quyết định:

  1. Outcome liên tục → kiểm tra phân bố
  2. Phân bố chuẩn → t-test
  3. Phân bố không chuẩn → Mann-Whitney
  4. Outcome phân loại → chi-square hoặc Fisher exact
shapiro.test(data$age[data$outcome == "yes"])
shapiro.test(data$age[data$outcome == "no"])

t.test(age ~ outcome, data = data)
wilcox.test(age ~ outcome, data = data)

chisq.test(data$sex, data$outcome)
fisher.test(data$sex, data$outcome)

Bài tập tuần 3: Chạy 4 phép kiểm khác nhau trên dữ liệu của bạn, ghi lại p-value, viết 1 đoạn Methods 5 dòng giải thích lý do chọn phép kiểm nào.

Tuần 4: So sánh nhiều nhóm + tương quan

Mục tiêu: ANOVA, Kruskal-Wallis, tương quan.

aov_result <- aov(age ~ stage, data = data)
summary(aov_result)
TukeyHSD(aov_result)

kruskal.test(age ~ stage, data = data)

cor.test(data$age, data$crp, method = "spearman")

Bài tập tuần 4: Tự xác định 1 câu hỏi nghiên cứu trong dataset có 3 nhóm trở lên (ví dụ: stage I/II/III). Chạy ANOVA hoặc Kruskal-Wallis. Viết kết quả 2 dòng cho Results.

Tuần 5: Linear regression

Mục tiêu: Khớp mô hình tuyến tính, đọc kết quả, viết Results.

model <- lm(crp ~ age + sex + bmi, data = data)
summary(model)
confint(model)

library(gtsummary)
tbl_regression(model)

Hiểu kết quả: Estimate (β), Std. Error, t-value, p-value, R-squared. Tuần này là tuần đầu bạn đụng "regression" thực sự. Đừng vội. Dành 4-5 buổi đọc kết quả từng dòng, cho đến khi hiểu mỗi số nghĩa là gì.

Sai lầm phổ biến: chạy regression với 10 covariate khi sample size < 50. Quy tắc 1:10 (events per variable) áp dụng. Nếu bạn có 30 outcome event, max 3 covariate trong model.

Tuần 6: Logistic regression + survival

Mục tiêu: Logistic cho binary outcome, Kaplan-Meier + Cox cho time-to-event.

Logistic:

model <- glm(outcome ~ age + sex + stage + comorbidity,
 data = data, family = binomial)
summary(model)
exp(coef(model))
exp(confint(model))

tbl_regression(model, exponentiate = TRUE)

Survival:

library(survival)
library(survminer)

fit <- survfit(Surv(time, event) ~ stage, data = data)
ggsurvplot(fit, pval = TRUE, risk.table = TRUE)

cox_model <- coxph(Surv(time, event) ~ age + sex + stage, data = data)
summary(cox_model)
tbl_regression(cox_model, exponentiate = TRUE)

Bài tập tuần 6: Gen Bảng 3 cho paper (univariate + multivariate logistic regression). Đây là bảng phức tạp nhất trong paper retrospective phổ biến. Sau tuần 6, bạn đủ kỹ năng cho 80% paper lâm sàng Q1.

Tuần 7: Vẽ hình đạt chuẩn xuất bản với ggplot

Mục tiêu: 5 loại hình thường gặp trong paper.

Histogram:

ggplot(data, aes(x = age)) +
 geom_histogram(bins = 20, fill = "steelblue") +
 theme_classic() +
 labs(x = "Age (years)", y = "Count")

Boxplot theo nhóm:

ggplot(data, aes(x = outcome, y = age, fill = outcome)) +
 geom_boxplot() +
 theme_classic() +
 labs(x = "Outcome", y = "Age (years)")

Scatter với regression line:

ggplot(data, aes(x = age, y = crp)) +
 geom_point() +
 geom_smooth(method = "lm") +
 theme_classic()

Forest plot (cho regression OR):

library(forestplot)
# hoặc dùng tbl_regression %>% plot()

KM curve: đã có ở tuần 6.

Bài tập tuần 7: Sao chép lại Figure 1 và Figure 2 của 1 paper Q1 bạn đã đọc. Dùng dữ liệu của bạn, không phải dữ liệu paper đó. Đây là cách học ggplot hiệu quả nhất.

Tuần 8: Rmarkdown + quy trình tái lập được

Mục tiêu: Đóng gói toàn bộ phân tích vào 1 file Rmd tạo tự động Methods + Results.

---
title: "Analysis cohort"
output: word_document
---

```{r setup, include=FALSE}
library(tidyverse)
library(gtsummary)
data <- read.csv("cohort.csv")

Methods

Median age was r median(data$age) years ...


**Lợi ích Rmd**: mỗi khi dữ liệu cập nhật, bạn click "Knit" 1 lần, toàn bộ Methods và Results section tự cập nhật với số mới. Không phải copy paste lại.

Một paper mình từng làm có nhiều lần bổ sung ca trong quá trình review. Mỗi lần re-knit chiếm 5 phút. Nếu là SPSS cộng Word manual, mỗi lần là 2-3 giờ.

**Bài tập cuối**: Đóng gói toàn bộ phân tích paper của bạn vào 1 file Rmd. Knit ra Word doc. So sánh với bản nháp Methods/Results hiện tại của bạn. Đó là kết quả hoàn chỉnh của 8 tuần.

## Sau 8 tuần: tiếp theo gì

8 tuần này đủ cho paper retrospective hoặc case-control phổ biến. Nếu bạn tiếp tục:

- **Meta-analysis**: học `metafor` (1-2 tuần)
- **Multilevel/mixed model**: học `lme4` (2-3 tuần)
- **Power calculation**: học `pwr` (3-4 buổi)
- **Quy trình tái lập được chia sẻ với cộng tác viên**: GitHub + RStudio Projects (1 tuần)

Đừng học hết một lần. Chỉ học khi paper tiếp theo cần.

## Sai lầm phổ biến trong 8 tuần

**Tuần 1-2**: học bằng dataset minh hoạ (mtcars, iris). Không bám lại. Phải dùng dữ liệu thật.

**Tuần 3-4**: bỏ qua lý thuyết thống kê. Học hàm R mà không hiểu phép kiểm giả định gì. Kết quả: chạy t-test trên dữ liệu không chuẩn, reviewer chê.

**Tuần 5-6**: chạy regression với 10 covariate trên 50 ca. Quá khớp, mô hình không ổn định. Quy tắc 1:10 phải áp dụng.

**Tuần 7**: copy thiết kế hình từ ví dụ minh hoạ chung chung. Không khớp phong cách journal mục tiêu. Đọc 3-5 paper trong journal mục tiêu trước khi tạo hình.

**Tuần 8**: bỏ qua Rmarkdown vì "phức tạp". Đó là tuần quan trọng nhất. Quy trình tái lập được là lý do chính học R thay vì SPSS.

Tôi đã viết chi tiết hơn về [5 thao tác R thay thế SPSS bác sĩ thường làm hằng ngày](/blog/5-thao-tac-r-thay-the-spss). Đọc kèm trong tuần 2-6 để có bối cảnh đối chiếu giữa SPSS click và R lệnh.

## Trường hợp thực: một bác sĩ nội trú học R trong 8 tuần

Bác sĩ mình hướng dẫn là một nội trú đã pass IRB cho một retrospective cohort cỡ trung bình. Trước khi học R, đã làm SPSS hai năm và viết một bài đăng tạp chí trong nước.

**Tuần 1-2**: Kẹt ở Excel header tiếng Việt. Sửa header 30 phút, sau đó nạp dữ liệu suôn sẻ. Bảng 1 bằng `gtsummary` chạy tuần 2, dán vào Word.

**Tuần 3-4**: Chạy 6 t-test, 4 chi-square cho paper. Gặp lỗi một lần khi dữ liệu có giá trị thiếu. Tôi giải thích `na.rm = TRUE`, sửa trong 5 phút.

**Tuần 5-6**: Đụng logistic regression. 4 biến covariate, khoảng 30 outcome event. Áp dụng quy tắc 1:10, bỏ một biến không có ý nghĩa thống kê ở phân tích đơn biến. Mất 2 buổi đọc kết quả.

**Tuần 7-8**: ggplot KM curve cho phân tích nhóm nhỏ. Sao chép lại Figure 2 của một paper Q1 trong cùng lĩnh vực. Đóng gói Rmd. Knit ra Word doc 8 trang Methods cộng Results.

Tổng: 8 tuần × 30 phút = 28 giờ. Kết quả: một paper draft Methods/Results hoàn chỉnh, reproducible, ready submit. Sau đó tiếp tục dùng R cho cohort thứ hai.

## FAQ thường gặp

**"Nếu mình không có dữ liệu thật thì sao?"** Đừng học. Đợi đến khi có IRB pass và dữ liệu sẵn sàng. R chỉ bám lại khi dùng cho dự án thật, không phải ví dụ minh hoạ.

**"30 phút/ngày có thực sự đủ không?"** Đủ nếu là 30 phút focus. Không đủ nếu vừa học vừa lướt Facebook. Đặt timer, đóng tab khác.

**"Có cần học statistics theory trước không?"** Cần biết 5 khái niệm: mean/median, normal vs non-normal, p-value, OR/HR, CI. Không cần học tới ANOVA two-way hoặc mixed model. Đủ để chạy 80% paper retrospective.

**"R hay Python tốt hơn?"** Cho nghiên cứu lâm sàng, R áp đảo. `gtsummary`, `metafor`, `survminer` là chuẩn học thuật. Python mạnh hơn cho ML hoặc phân tích hình ảnh, không phải thống kê mô tả đoàn hệ.

## Hỗ trợ cần thiết

1 bác sĩ tự học 8 tuần một mình có tỷ lệ hoàn thành ~50%. 1 bác sĩ học cùng 1 mentor hoặc khoá có lộ trình rõ có tỷ lệ ~80%. Khác biệt là khi gặp lỗi tuần 3, có người chỉ trong 5 phút thay vì 2 giờ Google.

Đó là lý do mình thiết kế khoá R-stats theo đúng lộ trình 8 tuần này, kèm dataset lâm sàng VN thật, code mẫu paste-được, và Q&A hằng tuần.

---

**Lộ trình 8 tuần này có khoá học đi kèm**: [R-stats trên tuyentranmd.com](https://tuyentranmd.com/courses/r-stats) đóng gói đúng 8 tuần này thành 30 phút mỗi ngày, kèm 5 dataset lâm sàng VN, code template, và Q&A hằng tuần. Thiết kế cho bác sĩ trực gác, không phải sinh viên data science.