系列:研究生自救指南:30 天用 Claude Code 打造我的論文工具箱 進度:第三週「資料」(Day 13–18)第 1 篇
檢體送到檢驗科,第一件事不是上機,是核對標籤。姓名、病歷號、採檢時間、檢體種類,四樣有一樣對不上,這管血再新鮮也不能用——不是檢驗科刁難,是結果出來之後沒有人能證明它是誰的。
Google 表單匯出的那份 CSV,就是那管血。它是我整篇論文結論的唯一證據(Day 4 講過),而我第一次打開它的時候,做的事跟直接上機沒兩樣:打開 Excel,看到亂的就刪,看到反向題就順手算,存檔。三個月後的後果,Day 18 再講。今天先講第三週的第一個工具,以及它為什麼跟前兩週的工具長得不一樣。
先看清楚那份檔案長什麼樣
Google 表單匯出成 CSV,打開之後大概是這樣(虛構示範,欄位依我的問卷改寫):
時間戳記 電子郵件地址 1. 您的性別 2. 您的年齡 3. 我對目前的工作感到精疲力竭 4. 您目前的工作單位(可複選)
2026/8/12 下午 9:47:13 xxx@gmail.com 女 34 非常同意 內科病房, 加護病房
六個坑,每一個都是我踩過的:
欄名是整句題目。 「3. 我對目前的工作感到精疲力竭」——含編號、標點、有時還有換行。統計軟體不吃這種欄名,人也記不住。
Likert 是文字不是數字。 「非常同意」是 5 還是 1,CSV 裡沒有寫,只在我的計畫書裡有寫。
多選題塞在一格。 「內科病房, 加護病房」——一格兩個答案,用逗號隔開,而 CSV 本身也是用逗號隔開的。
時間戳記是本機格式。 「下午 9:47:13」這種東西,換一台電腦打開就變另一種樣子。
有些列不是受試者。 我自己測試填的三筆、同一個人按兩次送出的重複填答、正式施測前的試填。哪些該留哪些該刪,看檔案看不出來。
個資欄還在。 電子郵件地址、(需作者補充:問卷裡還有哪些可以識別身分的欄位,例如員編、單位+年資組合)。這些欄位不該進到分析用的檔案裡,但它們在 raw 裡,而 raw 不能動。
這六件事沒有一件是「清理」能單獨解決的。每一件背後都有一個決定,而那個決定不在檔案裡,在計畫書裡。
第一步不是清理,是盤點
Day 8 的摘要卡教我的:先讓它讀,不要先讓它動。
第三週的第一個動作,是讓工具把 raw 讀一遍,輸出一份編碼簿(codebook)。它不改任何東西,只回答每個欄位四個問題:這欄原本叫什麼、裡面出現了哪些值、各出現幾次、空了幾格。
1 時間戳記 timestamp 2026/8/12 下午 9:47:13 … 0 本機格式,需轉 ISO
2 電子郵件地址 (移除) 87 種不同值 3 個資,不進 clean
3 1. 您的性別 gender 女(71)、男(16)、不願透露(2) 1
5 3. 我對目前的工作感到精疲力竭 bo_01 非常同意(12)、同意(31)、普通(25)、不同意(18)、非常不同意(4) 0 Likert 5 點,對應待定
6 4. 您目前的工作單位(可複選) unit 內科病房(40)、外科病房(22)、加護病房(19)、急診(11) 0 多選,需拆欄
這份表我印出來,拿著計畫書逐欄對。對的時候發現兩件事:計畫書的量表題號跟表單的題號差了一題(需作者補充:實際差在哪,例如表單前面多插了一題人口學變項);以及性別欄有一個「不願透露」的選項,計畫書裡根本沒有,是我做表單的時候手滑加的。
這兩件事,任何清理工具都不可能幫我發現,因為工具沒有讀過計畫書。盤點的目的就是逼我把兩份東西放在一起看。
規則檔:清理規則來自計畫書,不是來自看到的資料
跟 Day 11 的 apa-rules.md 一樣,清理規則獨立成一份檔案,放 data/clean-rules.md。不一樣的是:這份檔的每一條,出處都要是 IRB 核准的那一版計畫書。
_r;原欄保留這一次,它連副本都不寫——它寫程式
Day 11 我讓它改副本,判準是規則明確、結果可驗證、動作可逆。
資料清理三條都成立,但我還是把線畫得更緊:它不產出 data/clean/ 裡的任何檔案,它產出 analysis/clean_survey.py。清理後的檔案是我跑那支程式跑出來的。
原因回到 Day 4 原則二:clean 必須是可以重新生出來的。如果 clean 是它直接寫出來的,三個月後規則改了,我得再請它做一次,而它兩次做出來的不一定一樣。如果 clean 是程式跑出來的,規則改了就改程式重跑,跑一百次結果都一樣。
第二個原因更實際:程式我看得懂,它「做了什麼」我看不懂。一支八十行的 pandas 程式,每一段對應規則檔的一條,我可以逐條對回去。一份它直接產出的 CSV,我只能對結果,對不了過程。Day 12 說過,我要交代給老師的是過程。
SKILL.md 全文
存在 .claude/skills/survey-clean/SKILL.md:
| 步驟 | 依據(規則檔第幾條) | 處理前 N | 處理筆數 | 處理後 N |
表格下方:移除欄位清單、新增欄位清單、未涵蓋事項、建議人工確認清單
在專案資料夾啟動 claude,先打「盤點問卷」;對完 codebook、寫好規則檔之後,再打「清理問卷」。然後自己跑:
python analysis/clean_survey.py
報告長什麼樣
虛構數字:
步驟 依據 處理前 N 處理筆數 處理後 N
排除正式施測前填答 納入/排除第 1 條 92 3 89
排除重複 Email(保留最後一筆) 納入/排除第 2 條 89 2 87
排除量表全同一答案 納入/排除第 3 條 87 1 86
移除欄位:電子郵件地址 新增欄位:bo_03_r、bo_07_r(反向題);unit_med、unit_surg、unit_icu、unit_er(多選拆欄) 未涵蓋:第 12 題「其他(請說明)」自由填答欄,規則檔未定義處理方式 建議人工確認:第 41 列年齡填 3(疑似漏打一位數);第 58 列年資 35 年但年齡 28(邏輯矛盾)
最後那兩筆,三個月前的我會直接刪。現在它們留在 clean 裡、被列在報告上,等我拿計畫書決定。年齡填 3 的那筆,計畫書沒有定義「年齡不合理」算不算無效問卷——所以它現在還在。這不是工具不夠聰明,是我的計畫書當初沒想到。這一條要不要補進規則檔,我得先問老師,因為改了排除條件等於改了計畫書。
哪裡會出錯
它會順手清掉規則沒寫的東西。 第一版沒有「看起來像亂填也不動」那條,它在程式裡加了一段「移除年齡 < 18 或 > 70 的列」,註解寫「合理範圍」。合理範圍是誰定的?不是計畫書。這段程式碼我在逐條對規則的時候抓到,因為它對不到任何一條。這也是為什麼要求每段程式碼註解對應規則——對不到的就是它自己加的。
Likert 對應方向。 「非常同意=5」這件事我寫在規則檔裡,但它在盤點階段的建議備註寫了「非常同意=1」,因為訓練資料裡兩種都有。清理程式最後用的是規則檔的版本,但如果我沒寫規則檔,它會用它猜的那個,而且不會告訴我它在猜。
多選題的逗號。 Google 表單多選題用「, 」(逗號加空格)分隔,CSV 欄位用「,」分隔。第一版程式用 split(',') 切,「內科病房, 加護病房」切完第二個值前面多一個空格,變成「 加護病房」,跟「加護病房」對不上,拆欄結果全是 0。這種錯我是在 clean-report 看到 unit_icu 全部是 0 才發現的——報告裡的數字對不上 codebook 的次數,就一定有事。
看不見的 BOM。 Google 表單匯出的 CSV 開頭有一個看不見的 BOM 字元,第一欄欄名「時間戳記」讀進來會變成「時間戳記」,所有對欄名的比對全部失敗。(需作者補充:你是在哪一步發現的)。現在前置檢查第 3 條寫死了。
它想自己跑程式。 第一次它寫完程式之後直接問我「要執行嗎?」,我按了 y。程式跑完在 data/clean/ 產生了檔案——沒問題,但它同時「順便」在 data/raw/ 旁邊存了一份 survey_backup.csv。沒有壞事發生,但它碰了我說不能碰的資料夾。「不得自行執行」那條是這次之後加的:程式它寫,跑的人是我。
三週,四條線
第二週結束時我整理了三條線:它寫我核對、它報告我決定、它改副本我換正本。第三週的第一個工具畫了第四條:
它寫程式,程式產出副本,我跑程式、看報告、對規則。
多一層,是因為多一層的代價很低(跑一支程式),而少一層的代價是三個月後才發現的那種。文獻工作錯了是一筆引用錯;資料清理錯了,後面每一張表、每一個 p 值、每一段討論都建立在錯的東西上,而且看起來完全正常。
我還不確定的地方
「測試填答」的判定。目前靠時間戳記,正式施測日之前的都算測試。但我自己在正式施測日之後也填過一次確認表單沒壞,那筆用時間戳記抓不到,用 Email 可以(是我自己的),可是要把「我的 Email」寫進規則檔嗎?規則檔會跟程式一起交出去(需作者補充:你打算把 analysis/ 和規則檔當論文附錄,還是只留給老師看)。
遺漏值要在哪一步處理。清理階段我堅持不碰,但 Day 14 匯出 SPSS 時一定要決定遺漏值代碼(空白、−99、還是 9),而這個決定會影響 Day 15 之後所有分析。它到底是清理決定、匯出決定、還是分析決定,我還沒想清楚。
明天
Day 14:從 CSV 到統計軟體吃得下的樣子。變數名長度、值標籤、遺漏值代碼,以及一支產生 SPSS 語法檔的工具——輸出的不是 .sav,是能重生 .sav 的語法。