資料集呈現寬格式時,每一列代表單一實體(一個人、一個國家、一個感測器),每個測量變數各自佔一欄;同一份資料集呈現長格式時,每一列則是單一測量紀錄,並標註變數名稱與其數值。以寬格式來看,十名學生的數學與閱讀成績會是十列搭配兩個成績欄;以長格式來看,同樣的二十個成績則會展開成二十列,欄位包含 student_id、subject、score 等。數字本身從未改變,改變的只有排列方式。選對形狀,往往是圖表瞬間繪出與腳本跳出樞紐錯誤之間的差別。

這個問題反覆出現,是因為試算表與資料庫偏愛寬資料——它剛好塞得進一張螢幕;但幾乎所有分析與視覺化工具——ggplot2、seaborn、Tableau、Power BI、Excel 的 Power Query——都是為消化長格式表格而生的,那種「一列等於一筆觀測值」的結構。如果你曾盯著 pandas 的錯誤訊息,被要求「melt」你的資料框,或嘗試依類別對圖表進行分面(facet),卻被告知你沒有足夠的「tidy」資料,那你就正撞上這道鴻溝。事先掌握這條經驗法則,能省下好幾個小時的重工。

long format data vs wide format
long format data vs wide format

寬格式的樣貌

寬格式是人類把資料敲進表格時預設得到的形狀。每一列一個受測對象,每一欄一個變數。它既精簡又易於掃讀,非常適合並排比較,因為兩個相關數字就坐在相鄰的儲存格裡。

學生數學成績閱讀成績自然成績
Alex827488
Bea918579
Cal687265

它的優點顯而易見:你只要掃一眼 Cal 那一列,就能同時看到所有成績。但缺點在你想要畫「依科目區分的成績」那一刻就出現了——根本沒有單一的「score」欄位可供繪圖工具讀取,你只能手動新增三個資料序列。寬資料也會隨著變數增加而橫向膨脹,一旦每個實體的測量項目超過一打,就會變得難以掌控。

長格式的樣貌

長格式每列儲存一個測量值。每一列都帶有識別欄(誰或什麼被測量)、變數名稱(測量了什麼)以及數值(測量結果)。同樣的三位學生,在長格式下會變成九列。

學生科目成績
Alex數學82
Alex閱讀74
Alex自然88
Bea數學91
Bea閱讀85
Bea自然79

長資料較「高」,有時甚至高出許多,但它對應到統計學上對「資料點」的定義。Hadley Wickham 的 tidy data 原則——「每一列是一筆觀測值,每一欄是一個變數」——描述的正是長格式。當代多數工具都預設這種形狀:ggplot2 的美學映射、seaborn 的長格式 `data=` 引數、Excel 的 Unpivot,以及 SQL 風格的彙總,全都圍繞著它運作。

何時該用哪種格式

選擇的依據是「接下來誰要讀這份資料」,而不是個人偏好。

  • 選用寬格式的時機:資料會出現在列印報表、樞紐式摘要,或人類需要跨欄比對儲存格的小型表格中。寬格式對矩陣式運算,以及引用固定儲存格的試算表公式也更友善。
  • 選用長格式的時機:你要餵資料給繪圖函式庫、執行統計模型,或建立依變數篩選的儀表板時。長格式可以順暢擴充到數十個變數,因為新增一個變數只會多出列數,而不會新增欄位、打壞所有公式。
  • 選用長格式的時機:變數會隨時間變動時,因為每個測量日期都建立一個「寬格式日期欄」很快就會爆炸成數十欄(每個測量日期一欄),而長格式只是多塞幾列數值進去。

一條實用的經驗法則:資料輸入階段用寬格式,進入分析前再重塑成長格式,只有在需要最終摘要表時才樞紐回寬格式。

兩種格式之間的重塑

長與寬之間的轉換是機械化且無損的。在 pandas 中,melt 把寬變長,pivot 把長變回寬。在 R 中,reshape2tidyr 套件提供 melt/dcastpivot_longer/pivot_wider 來完成同樣的工作。在 Excel 中,Power Query 的「取消樞紐欄位」與「樞紐欄位」按鈕把同樣邏輯包進選單。背後的想法始終相同:辨識出保持固定的識別欄、辨識出要被堆疊(或展開)的變數欄,剩下的列運算交給工具處理。

當你要重塑的變數是物理測量值——身高、距離、重量——時,實際數字往往需要連同單位一起轉換,而非僅僅改變形狀。一個標記為「height_cm」的欄和另一個標記為「height_in」的欄,描述的是同一個屬性,只是單位不同;tidy 工作流程通常會在分析之前,把它們統一成同一欄、同一單位。這正是單位轉換工具派上用場的地方。長度轉換器能在毫米、公分、公尺、公里、英吋、英呎、碼、英哩、海哩之間任意切換長度值,讓長格式表格中的每一欄都能共用單一單位。開啟「一次顯示所有單位」,就能輕鬆抽查整欄結果:貼上一個具代表性的值、掃讀各輸出,再用單一公式標準化其餘資料。

重塑時如何同時轉換長度值

當你要取消樞紐的欄位混雜著不同單位時,請先把它們標準化,再進行堆疊。長度轉換器(位於 Lizely)只要三步就能完成標準化。

  1. 在長度值欄位中輸入你想轉換的距離。
  2. 在「From」下方選擇來源單位、在「To」下方選擇目標單位——例如公分轉英吋。
  3. 立刻讀取轉換結果,或勾選「一次顯示所有單位」,即可一次看到毫米到海哩的所有結果。

一旦掌握換算係數——例如,根據 1959 年國際碼與磅協議,1 英吋恰好等於 25.4 毫米——你就能把整個「height_in」欄乘以 25.4,讓每一列都對應到長格式模型所期待的「height_mm」欄。這個單一常數就是你唯一需要背下的換算係數;其餘單位——尤其是較少見的海哩或測量英尺——用工具查會比自行查表更快。

實作範例:取消三個測量欄位的樞紐

假設你有一張運動員的寬格式表格,欄位包含 iddash_100mlong_jump_mhigh_jump_m,每個距離都以公尺儲存。你想要得到一個名為 distance_m 的長欄位。使用 pandas:

  1. 載入表格:df = pd.read_csv("athletes.csv")
  2. 將三個測量欄位 melt:long = df.melt(id_vars="id", value_vars=["dash_100m","long_jump_m","high_jump_m"], var_name="event", value_name="distance_m")
  3. 確認列數:3 欄 × N 位運動員 = 3N 列。對數值本身並不做任何運算——改變的只有排列方式。

如果同一份檔案的三個欄位混雜了公尺與英呎,你應該先用「長度轉換器」抓到的係數(1 英呎 = 0.3048 公尺,精確值)逐一標準化每個欄位,然後再 melt。請注意,換算係數是你唯一需要的數字;列數與變數名稱本身並不藏任何隱含假設。

重塑時常見的陷阱

即使工具選對了,有些錯誤仍會一再絆倒人。

  • 忘了指定識別欄。如果 melt 時未指定 id_vars,原本的列索引會消失,每筆測量都會變得沒有對象。在展開之前,務必先鎖定至少一個識別欄。
  • 同一欄內混合了不同單位。一個「height」欄同時放著 182 與 5'11",會悄悄扭曲任何彙總結果。請先用「長度轉換器」轉換,再進行 melt。
  • 重塑兩次並累積誤差。單趟來回的轉換是精確的,但若在兩趟之間過濾了列,那這趟來回就不再是雙射( bijection)。請決定好最終形狀,並從原始來源直接重塑一次到位。
  • 把寬格式當成萬用預設。如果你的工具一直要求長資料,正確做法是在管線初期就重塑,而不是每張圖都重試一次。

為下一個專案挑選正確的形狀

日常的試算表工作,就維持寬格式——人眼讀它最快。任何會呼叫繪圖或建模函式庫的工作,就預先切換成長格式,只有需要列印摘要時才再樞紐回寬格式。當各欄單位不一,請在開始 melt 之前先用「長度轉換器」標準化,讓每個「value」欄都說同一種語言。如果工作流程延伸到日期或重量,同樣的重塑邏輯依然適用;當欄位大小面臨溢位威脅時,可以借助「資料儲存單位轉換器」;當你得到的長欄位其實是比率而非測量值時,則可以交給「百分比計算機」。養成這些習慣之後,「長格式 vs 寬格式」就不再是反覆出現的問題,而會變成在每次分析開頭做一次的單一決策。

延伸閱讀:電動車充電成本 vs 汽油:即時比較加油成本

如果你正在權衡選項,互動式元素週期表如何運作:完整解析對此有詳細說明。