報表式 vs 資料式:同一份 Excel 的兩種存法,決定後面每一步好不好走

資料整理
Excel
AI工具
同樣是「各縣市 × 年齡層 × 性別人口」,用給人看的報表存 vs 用一列一觀察存,差在哪?為什麼交給 AI、Python、R、樞紐分析時,後者總是省一大截時間。
發佈於

2026年7月6日

打開一份從主計總處抓下來的 Excel,常會看到兩種完全不同長相的表。一種表頭好幾層、儲存格合併來合併去,看起來像是設計來列印給主管翻的;另一種只有一列表頭,欄名就是「縣市、年齡層、性別、人數」,看起來很無聊,但每一列就是一筆觀察值。

這篇要講的就是這兩種存法的差別 —— 「報表式」(cross-tab / 交叉表,給人看的)和「資料式」(tidy / 乾淨資料,給程式看的)—— 以及為什麼你如果要拿去做分析、丟給 AI、跑樞紐,兩者的處理成本會差到讓人有感。

兩種表在講同一件事,但長相完全不同

先用一個簡化的例子。假設我們手上有「三個縣市 × 兩個年齡層 × 兩性人口」的資料。

報表式大概長這樣(真的用 Excel 做出來截下來的 —— 表頭有兩層,「男 / 女」跨欄合併、下面再切「0–14 / 15+」,最後多一列「總計」):

報表式 Excel 表格截圖

Excel 報表式:多層表頭 + 跨欄合併 + 總計列

另一種常見的合併是用 rowspan(跨列合併儲存格)做區域分組 —— 同一個「區域」名字只寫在第一列,下面幾列的儲存格被合併起來共用:

用 rowspan 分組的 Excel 表格截圖

Excel 報表式:區域欄位跨列合併

眼睛看很清楚:「新北市」跟「桃園市」也是北部。但程式讀進來只有第一列有「北部」,下面兩列的「區域」欄位都會變成 NaN(遺失值 —— pandas 的 read_excel 預設會把合併儲存格底下的位置填成這個),要自己再 forward fill(向下填充:把上一列的值抄下來)一次才對。

資料式是同一份資料,但攤平成一列一筆:

資料式長表 Excel 截圖

Excel 資料式(長表):一列一個「縣市 × 年齡層 × 性別」的觀察值

看起來資料式好像變得很長、很囉唆,但這種寫法有一個核心優點 —— 每一格的意義完全固定:這一列的第 4 欄,就是「人數」,不會因為你在第幾欄而改變意思。

先澄清一件事:資料式(tidy)不等於「長表」

看到上面這個攤平的樣子,很容易誤會「愈長愈瘦才叫資料式」。其實不是。資料式的定義是「一列一個觀察值、一欄一個變數」,跟表格寬窄沒有直接關係。

同一份資料,下面這樣也算資料式

資料式寬表 Excel 截圖

Excel 資料式(寬表):性別攤成「男人數」和「女人數」兩欄,仍然一列一觀察

它是「寬」的,但每一欄的意思都固定:「男人數」就是這一列這個縣市這個年齡層的男性人口數。沒有把兩個變數塞在同一個欄名裡,也沒有多層表頭、沒有小計混進來 —— 程式讀進來一樣直覺。

換句話說,報表式真正的問題不在「寬」,而在下面這幾件事同時發生

  • 欄名同時裝了多個變數(「男 0–14」= 性別 + 年齡層)
  • 表頭跨兩層以上,需要合併儲存格才顯示得出來
  • 小計、總計混在資料列裡
  • 用空白列或空白欄來分區

把這幾件事拿掉,剩下的表就算是資料式。至於要不要更進一步把「男人數」、「女人數」再攤成一欄「性別」加一欄「人數」,是後續分析方便性的問題(例如畫 ggplot 時 long 通常比較好用),不是資料式的必要條件。

為什麼報表式在程式眼裡很難讀?

把上面那張報表式的表倒過來想一次,你會發現它塞了很多隱藏資訊

  • 「男 0–14」這個欄名,其實同時裝了「性別=男」和「年齡層=0–14」兩個變數
  • 表頭是兩層合併的,第一列寫「男」、第二列寫「0–14」,程式讀進來只會看到一堆錯位的欄名
  • 最後那一列「總計」不是資料,是統計結果,混在一起會讓平均、加總都算錯
  • 如果原表還有「空白列分區」(例如北部縣市一區、中部一區、中間插一列空的),程式讀進來會出現一堆 NA(遺失值,R 的講法;Python 則叫 NaN,同一件事)

這些東西人眼看一眼就懂,但 AI 或程式讀進來會遇到的問題:

  • 要花很多 token(AI 模型讀寫文字的計算單位,愈長愈貴)猜表頭:你把整張 Excel 貼給 ChatGPT,它得先讀懂「這一欄的『男』跟上面那一欄的『男』是不是同一件事」,然後才能回答你的問題。猜錯的機率也不低。
  • 每個小計都要跳過:不然算平均會把「總計那一列」也算進去,數字全歪
  • 合併儲存格會變空白:pandas 讀進來,只有第一格有值,下面幾格都是 NaN(遺失值),要自己 forward fill(向下填充)

資料式就沒有這些問題。你把它丟給 AI:「幫我算各縣市男女比例」,它一看就知道要 groupby(縣市, 性別)(依「縣市 + 性別」分組再加總)操作,寫兩行就完成。

兩種格式各自的位置

不是說報表式就沒用。它有它的場景:

情境 報表式 資料式
印出來給主管看一眼 適合,一頁就看完 太長,翻不完
給 Python / R 讀進來 groupby 要先攤平,多一步 直接讀,直接算
Excel 樞紐分析的「資料來源」 樞紐吃不下多層表頭 樞紐的標準輸入
貼給 AI 問問題 要花 token 解釋表頭 prompt 可以很短
畫圖(ggplot / matplotlib) 幾乎都要先攤平 直接對應 x/y/color

所以兩者不是誰取代誰,而是用途分工。差別在於:如果你手上只能留一份「原始檔」,留哪一種對後續每一步都比較省力?

一個實務上的順序建議

一個常見的做法是這樣:

  1. 原始蒐集、儲存階段用資料式 —— 每次新增資料就 append(追加到最後)一列,欄位固定,不用改結構
  2. 要給人看的時候再從資料式 pivot 出報表式 —— Excel 樞紐、R 的 pivot_wider()、Python 的 df.pivot() 都是一行的事
  3. 從別人那邊拿到報表式(例如政府開放資料常常是報表式)—— 花一點時間攤平成資料式,之後不管做幾次分析、換幾次工具,都不用再拆一次表頭

反過來的順序 —— 只留報表式、每次要分析就重新拆 —— 表頭一改就要重寫一次拆表邏輯,換一種分析角度又要拆一次。

Excel 樞紐分析:從資料式一鍵切成報表式

如果你手上是資料式(四欄:縣市、年齡層、性別、人數),要生上面那張報表:

  1. 選整個範圍 → 插入 → 樞紐分析表
  2. 「列」放「縣市」
  3. 「欄」放「性別」和「年齡層」
  4. 「值」放「人數」(加總)

樞紐就會幫你切出多層表頭的報表式,順便附上小計、總計。但這張樞紐報表只當「輸出」,不要拿去當下一步分析的「輸入」,不然又走一次剛才講的老路。

R 的 pivot_longer / pivot_wider

R 的 tidyverse 有一組專門重塑表格形狀的函數:tidyr::pivot_longer() 把寬表變長、pivot_wider() 把長表變寬。它們處理的是「同一份資料式的不同排列」,不是把資料式變成報表式 —— 報表式的多層表頭、小計、合併儲存格,這兩個函數處理不了,要先手動清掉。

從寬的資料式撐成報表式的欄位結構(或是要給樞紐用):

library(tidyr)
library(dplyr)

# df_long 是資料式:縣市、年齡層、性別、人數
df_wide <- df_long |>
  pivot_wider(
    names_from = c(性別, 年齡層),   # 這兩欄變成新的欄名
    values_from = 人數
  )

從已經是資料式、但欄名包了兩個變數的寬表,攤成一列一觀察的長表(假設欄名是「男_0–14」、「男_15+」、「女_0–14」、「女_15+」):

df_long <- df_wide |>
  pivot_longer(
    cols = -縣市,                     # 縣市這欄不動,其他都攤
    names_to = c("性別", "年齡層"),
    names_sep = "_",
    values_to = "人數"
  )

Python pandas 對應的是 df.melt()df.pivot(),邏輯一模一樣。

給 AI 資料時,格式差異會直接反映在正確率

這是最近很有感的一點。同一個問題「算一下各縣市女性 15 歲以上的人口比例」:

  • 貼報表式 Excel 給 ChatGPT → 它要先花一段回覆解讀表頭、確認哪一欄是女性 15+,中間還可能問你「總計那一列要不要算」,來回三四輪才會給答案。而且合併儲存格轉成文字後常常整個亂掉。
  • 貼資料式 → 一句「請幫我算 性別=='女' & 年齡層=='15+' 的人數佔各縣市總人口的比例」就結束,AI 直接寫 code 給你,不用猜。

你的 prompt(提示語,就是你打給 AI 的那段話)可以短、AI 的答案可以準,很大一部分不是 prompt 工程的差別,是資料格式的差別。

小結

同一份資料,存成報表式還是資料式,是兩種完全不同的世界觀:報表式服務「這一頁要好讀」,資料式服務「這一列要好算」。原始蒐集階段留資料式,需要給人看的時候再 pivot,之後不管換到 Excel、R、Python,還是丟給 AI,都能省下一大截「先攤平」的時間。

提示

拿到別人給的報表式檔案時,可以先問一句:「這份原始資料式的版本可以給我嗎?」很多時候對方手上就有,只是預設把好看那份寄出來。

註釋

本文用到的 Excel 範例檔(含四張工作表:報表式-多層表頭、報表式-區域分組、資料式-寬、資料式-長):report-vs-tidy-example.xlsx

回到頂端