source("START.R")
# START.R 是「一鍵入口」:它會幫你呼叫 setup/install.r 把套件全部裝好。
#
# 進階 / 想直接呼叫安裝腳本:
# source("setup/install.r")
#
# 或完全手動:
# options(repos = c(CRAN = "https://packagemanager.posit.co/cran/latest"))
# install.packages("pak")
# pak::pak(c("tidyverse","gtsummary","mmrm","emmeans","broom","broom.mixed",
# "survival","survminer","gt","patchwork","ggsci"))1 Part 1:認識 paper + 認識資料
預計時間:30–40 分鐘。 這一章你會:把工作環境弄好、用 AI 摘要 paper、用 R 讀進模擬資料。
如果你已經在 RStudio / Posit.Cloud 開好了,可以直接複製下面這段給 AI,一次跑完本章:
我手上有兩個 csv:
data/faricimab_baseline.csv(一筆病人一列,欄位有 patient_id, arm, study, region, age, sex, bcva_baseline, cst_baseline, irf_baseline, srf_baseline, bcva_strat, lld_strat)和data/faricimab_followup.csv(long format,每筆病人 × 回診一列,欄位有 patient_id, week, bcva, cst, irf, srf)。請給我一段 R code:
- 用
readr::read_csv()讀入這兩個檔案- 用
dplyr::glimpse()印出欄位結構- 算出 baseline 中兩臂的人數(
arm是faricimabvsaflibercept)- 算出 followup 中每個 week (4/8/12) 的 row 數量
請加上中文註解,每段都可以直接貼到 RStudio 跑。
1.1 任務 1:開好 Posit.Cloud
老師會在現場給你一個 Posit.Cloud 連結——那是「預烤好的 project」,套件都已經幫你裝好了。
📋 拿到那個連結後:
- 打開瀏覽器、貼上連結
- 用 Google 帳號登入 Posit.Cloud(免費)
- 右上角點 Save a Permanent Copy(把這份 project 存成你自己的)
- RStudio 會開起來,套件已裝好
- 右下角 Files 視窗 → 雙擊
part1.qmd
整個過程 < 30 秒。
Plan B(自己 fork): 1. Posit.Cloud → New Project → New Project from Git Repository 2. 貼 https://github.com/htlin222/roche-vabysmo-rwe-workshop 3. RStudio 開起來,Console 跑 source("START.R"),等 5–10 分鐘 4. 之後跟 Plan A 一樣
Plan C(完全沒 R 環境): 直接讀 https://htlin222.github.io/roche-vabysmo-rwe-workshop/。 你看不到自己改 csv 的效果,但內容都讀得到。可以跟旁邊的同學共用螢幕做 hands-on。
- 「中文亂碼」→ Tools → Global Options → Code → Saving → Default text encoding 改
UTF-8 - 「畫面卡住」→ 重整頁面,Posit.Cloud 偶爾會 idle disconnect
- 「
Save a Permanent Copy是灰的按不下去」→ 你還沒登入,右上角點人頭 → Sign In
每個「📋 複製這段話,貼給 AI」都標了該 開新對話 還是 接續上一個——這是用免費版 AI 的關鍵習慣:
- 🆕 開新對話:開一個全新 chat。用在「概念問答」或「某個新主題的第一個 code 任務」。免費版 AI 的上下文(記憶)長度有限,把無關內容塞進同一個對話會讓它變慢、變鈍、甚至忘記前面的設定。概念問答問完可直接關掉;若這是一段 code 流程的起點,請留著這個對話給接下來的 ↩︎️ 續前對話 用。
- ↩︎️ 續前對話:在「剛剛那個對話」裡繼續問。用在「改剛剛那段 code」「把剛剛的表存檔」「沿用剛剛建好的 model / 變數」——AI 需要記得前面產出的內容才接得下去。
小訣竅:每開一個新對話,第一句先貼 glimpse(df) 的輸出,AI 才不會幻想欄位名(見 Appendix C)。
1.2 任務 2:第一次安裝套件
📋 複製這段話,貼給 AI(🆕 開新對話):
我在 Posit.Cloud 上的 RStudio,請給我一段 R code 安裝這些套件:tidyverse, gtsummary, mmrm, emmeans, broom, broom.mixed, survival, survminer, gt, patchwork, ggsci。請用 pak 套件,repo 設成 Posit Public Package Manager 來加快下載。
1.2.1 參考程式碼
第一次跑大約 3–5 分鐘。之後不用再裝。
1.3 任務 3:讓 AI 用 100 字摘要這篇 paper
📋 複製這段話,貼給 AI(🆕 開新對話):
下面是一篇 Ophthalmology 期刊的 abstract,請用繁體中文 100 字內告訴我:(1)它在比較哪兩個藥;(2)為什麼比較;(3)主要結論;(4)用了什麼統計方法。
【貼上 abstract — 在
refs/tenaya-lucerne-paper.pdf第 1 頁】
你會發現 AI 摘出來的「統計方法」一定會提到 MMRM 與 CMH-weighted——這就是今天 Part 3 / Part 4 要做的事。
1.4 任務 4:讀進模擬資料,看欄位
我們已經幫你準備好兩個 csv(在 data/ 資料夾下)。 這份資料不是真的病人資料,是用 R 模擬出來的,但統計特性接近 TENAYA/LUCERNE paper。
📋 複製這段話,貼給 AI(🆕 開新對話):
請給我 R code,用
readr::read_csv()讀入data/faricimab_baseline.csv和data/faricimab_followup.csv,然後用dplyr::glimpse()看欄位。請加中文註解。
1.4.1 參考程式碼
library(readr)
library(dplyr)
baseline <- read_csv("data/faricimab_baseline.csv", show_col_types = FALSE)
followup <- read_csv("data/faricimab_followup.csv", show_col_types = FALSE)
glimpse(baseline)Rows: 1,329
Columns: 12
$ patient_id <chr> "P0001", "P0002", "P0003", "P0004", "P0005", "P0006", "P…
$ arm <chr> "faricimab", "aflibercept", "aflibercept", "faricimab", …
$ study <chr> "LUCERNE", "LUCERNE", "TENAYA", "LUCERNE", "TENAYA", "LU…
$ region <chr> "US-Canada", "US-Canada", "Rest-of-world", "Rest-of-worl…
$ age <dbl> 64, 83, 56, 73, 78, 60, 68, 81, 85, 80, 77, 79, 60, 76, …
$ sex <chr> "F", "M", "F", "F", "F", "F", "F", "F", "F", "M", "F", "…
$ bcva_baseline <dbl> 64, 79, 76, 73, 74, 46, 81, 55, 67, 45, 74, 71, 53, 69, …
$ cst_baseline <dbl> 300, 381, 290, 382, 381, 496, 240, 539, 328, 310, 378, 4…
$ irf_baseline <dbl> 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1,…
$ srf_baseline <dbl> 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1,…
$ bcva_strat <chr> "55-73", ">=74", ">=74", "55-73", ">=74", "<=54", ">=74"…
$ lld_strat <chr> ">=33", "<33", "<33", ">=33", "<33", "<33", "<33", "<33"…
glimpse(followup)Rows: 3,987
Columns: 6
$ patient_id <chr> "P0001", "P0001", "P0001", "P0002", "P0002", "P0002", "P000…
$ week <dbl> 4, 8, 12, 4, 8, 12, 4, 8, 12, 4, 8, 12, 4, 8, 12, 4, 8, 12,…
$ bcva <dbl> 69, 74, 71, 86, 78, 83, 80, 73, 78, 79, 85, 85, 83, 85, 92,…
$ cst <dbl> 142, 110, 148, 368, 306, 286, 166, 143, 128, 187, 250, 219,…
$ irf <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,…
$ srf <dbl> 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0,…
1.4.2 看一下兩臂人數對不對
baseline |>
count(arm)# A tibble: 2 × 2
arm n
<chr> <int>
1 aflibercept 664
2 faricimab 665
(對照 paper:faricimab 665、aflibercept 664)
1.4.3 每個 week 有多少筆?
followup |>
count(week)# A tibble: 3 × 2
week n
<dbl> <int>
1 4 1329
2 8 1329
3 12 1329
每個 visit 應該都接近 1329 筆(會少一點點,因為有 missing)。
1.5 任務 5:long format vs wide format
📋 複製這段話,貼給 AI(🆕 開新對話):
請用「給小學生聽得懂」的方式,告訴我什麼是 long format(長表格)跟 wide format(寬表格)。為什麼 longitudinal data(同一個病人測多次)通常存成 long format?
1.5.1 參考解釋
| 格式 | 一筆 row 是什麼 | 例子 |
|---|---|---|
| wide | 一個病人 | patient_id, bcva_w0, bcva_w4, bcva_w8, bcva_w12 |
| long | 一個病人 × 一次測量 | patient_id, week, bcva |
MMRM 需要 long format——因為它把「同一隻眼睛被量很多次」當成 random effect 來建模,需要每次測量都是獨立一筆。
我們的 followup 已經是 long format。Part 3 馬上會用到。
- Posit.Cloud 是「在瀏覽器裡跑 RStudio」,零安裝
- AI 是你的 R 助手,但你要看懂結果
data/faricimab_baseline.csv是病人層級、data/faricimab_followup.csv是回診層級- MMRM 吃 long format,等下會看到