1.5 用 rstatistics 看資料#
本節目標#
- 把 1.1–1.4 的工具串成一條完整的 EDA(Exploratory Data Analysis,探索式資料分析)流程
- 實戰一組 28 筆的真實感資料:
r.summary、r.table類別統計、r.rank與r.scale的用途 - 完成整章回顧練習
EDA:Tukey 留下的工作方式#
John Tukey 在 1977 年出版《Exploratory Data Analysis》,主張:拿到資料先畫圖、先算摘要,別急著套模型。本章學的每個工具都是 EDA 的一站;本節把它們走一遍。
流程如下:
flowchart LR
A[1. 原始資料] --> B[2. summary 五數摘要]
B --> C[3. 圖形 hist / boxplot]
C --> D[4. 離群值追查]
D --> E[5. 類別化 table]
E --> F[6. 標準化 scale / rank]資料:某班 28 位學生的體重#
import rstatistics as r
g = r.set_seed(2026)
w = [round(v, 1) for v in g.rnorm(28, mean=62, sd=8)]
print(w)
輸出:
[66.2, 53.4, 63.1, 61.3, 56.7, 41.9, 56.1, 53.8, 62.9, 58.2, 58.7, 56.2, 60.2, 60.2, 41.6, 72.8, 66.9, 63.7, 55.6, 67.5, 59.4, 60.7, 50.9, 73.7, 62.4, 77.3, 75.8, 62.5]
第一站:五數摘要#
print(r.summary(w))
輸出:
Min. 1st Qu. Median Mean 3rd Qu. Max.
41.60 56.18 60.45 60.70 64.33 77.30
解讀:中位數 60.45 與平均 60.70 很接近(資料大致對稱); \(\`Q_3 - Q_1 \approx 8.15`\) 、全距 35.7。沒有明顯偏斜,可以放心用 mean/sd 這一組(1.2、1.3 節的選擇法則)。
第二站:直方圖與箱型圖#
g1 = r.Graphics(width=7.0, height=4.5)
g1.hist(w, main="班上體重分布", xlab="體重 (kg)")
g1.save("img/w_hist.svg")
g2 = r.Graphics(width=7.0, height=4.5)
g2.boxplot(w, main="班上體重箱型圖", ylab="kg")
g2.save("img/w_box.svg")
輸出:
(無文字輸出;w_hist.svg 與 w_box.svg 已存檔)
圖:重量資料的直方圖、重量資料的箱型圖。
直方圖顯示資料集中在 55–65,左邊拖著兩個 41.x 的值;箱型圖用它們檢查(r.boxplot_stats(w).out 是空串列)確認這兩個值還在 \(1.5 \times \mathrm{IQR}\) 界內——是「偏輕」,不是「離群」,差別在第 1.4 節的規則。
第三站:類別化與 r.table#
連續值常切成類別看組成。把體重三等分:
cat = ["偏輕" if x < 56 else ("標準" if x <= 68 else "偏重") for x in w]
print(r.table(cat))
輸出:
x
偏輕 偏重 標準
6 4 18
28 人中「標準」18 人、「偏輕」6 人、「偏重」4 人。r.table 對應 R 的 table(),給次數表——描述統計裡最古老、也最常被低估的工具。
第四站:r.rank 與 r.scale#
r.rank:給出每個值的名次(並列值取平均名次)。它本身不玄,但它是第 9 章無母數檢定(Wilcoxon、Spearman)的原料——那些檢定只看名次不看數值,因此對離群值免疫。r.scale:z 分數,讓「我的體重在這班算幾個標準差之外」變成一個可比較的數。
print(r.rank(w)[:8])
z = r.scale(w)
print([round(v, 3) for v in z[:8]])
print(r.mean(z), r.sd(z))
輸出:
[22.0, 4.0, 20.0, 16.0, 9.0, 2.0, 7.0, 5.0]
[0.643, -0.855, 0.28, 0.07, -0.469, -2.201, -0.539, -0.808]
-2.1807952269422717e-17 1.0
第一筆 66.2 是全班第 22 名、z 分數 0.643;第 6 筆 41.9 的 z 分數 −2.20——低於平均兩個標準差以上,值得多看一眼(但按箱型圖規則仍非離群值)。
一條 EDA 流程的完整劇本#
把上述整理成你以後每次拿到新資料的固定動作:
r.summary(x):五數 + 平均,30 秒掌握位置與離散;- mean vs. median:差很多 → 有偏斜或離群值 → 改用 median/IQR/MAD(1.2、1.3);
- 畫圖:
hist看形狀、boxplot點名離群值(1.4); - 離群值追查:每個被 1.5×IQR 點名的值都要能回答「量測錯誤?真實極端?還是值得研究的個案?」;
- 類別化:
r.table看組成(1.5); - 標準化:
r.scale/r.rank為後續比較與檢定鋪路。
EDA 不是檢定的前置雜務,而是產生假說的地方:1.1 節的抽樣迴路告訴我們統計量會波動,1.2–1.4 節的工具讓我們看清楚手上這個樣本長什麼樣,第 7 章起再教我們對波動計帳。
一個新手常見的陷阱:看到離群值就刪#
把一個 130 kg 的資料塞進我們的體重資料(可能是磅秤壞了,也可能是一位真的特別重的學生——你不知道之前不能動手):
g = r.set_seed(2026)
w = [round(v, 1) for v in g.rnorm(28, mean=62, sd=8)]
w2 = w + [130.0]
print(r.mean(w), r.sd(w))
print(r.mean(w2), r.sd(w2))
print(r.median(w2), r.mad(w2))
st = r.boxplot_stats(w2)
print(st.out)
輸出:
60.70357142857143 8.544111341990963
63.09310344827586 15.361662183000593
60.7 6.819960000000002
[130.0]
一個點讓平均加了 2.4、標準差幾乎翻倍(8.5 → 15.4);中位數與 MAD 幾乎不動,boxplot_stats 也正確地把它點名出來。正確的處理順序是:
- 先追查:磅秤錯?抄錄錯?還是真實值?
- 查得到是錯誤 → 修正或剔除,並在報告裡寫明;
- 查不到 → 保留它,改用穩健度量(median/IQR/MAD)描述,或兩組數字並陳。
「先算 boxplot、再決定要不要相信 mean/sd」正是本章所有工具的分工。
與 R 對照#
set.seed(2026)
w <- round(rnorm(28, 62, 8), 1)
print(summary(w))
print(table(cut(w, c(0, 56, 68, Inf), labels = c("偏輕", "標準", "偏重"))))
print(head(rank(w)))
print(round(head(scale(w)), 3))
輸出:
Min. 1st Qu. Median Mean 3rd Qu. Max.
41.60 56.17 60.45 60.70 64.33 77.30
偏輕 標準 偏重
6 18 4
[1] 22 4 20 16 9 2
[1] 0.643 -0.855 0.280 0.070 -0.469 -2.201
逐項對得上(R 的 summary 顯示 56.17 與 rstatistics 的 56.18 只是小數位取捨差異)。注意 R 用 cut() 做類別化,我們用 list comprehension——概念相同。
小結#
- 一條 EDA 流程:summary → 圖形 → 離群值追查 → table 類別化 → scale/rank 標準化。
r.summary/r.table/r.rank/r.scale加上Graphics,就是本章全部工具的實戰組合。- mean/median 接近 → 用 sd 組;差很遠 → 用 median/IQR/MAD 組——這條法則貫穿全章。
- 本章回答「這份樣本長什麼樣」;接下來的章節回答「這個樣本對母體說了什麼」。
練習(第 1 章總回顧)#
- 全流程:用
g = r.set_seed(11)抽g.rnorm(25, 100, 5),走完上面六步 EDA,每步一行結論。 - 離群值實驗:在練習 1 的資料塞一個
999,重算 summary、sd、mad、boxplot_stats。哪些量變了、哪些沒變?對應 1.2/1.3 節的什麼性質? - Bessel 再現:不查書,用 20 字以內說明「為什麼樣本變異數除 \(n-1\) 而非 \(n\) 」,再用
n = 5的模擬驗證你的說法(1.3 節)。 - hinge vs type 7:造一組 9 個數,找出 hinge 與 type 7 給出不同 \(Q_1\) 的情況,並各畫一次箱型圖(1.4 節)。
- 歷史串聯:用 100 字把以下四件事連成一個故事——1936 年 Literary Digest 的偏差、1948 年配額抽樣的失誤、Tukey 的 EDA(1977)、以及你寫程式時「先設種子」的習慣。(提示:偏差無法靠 \(n\) 消除;隨機性讓誤差可計算;可重現性讓計算可驗證。)