【R 語言】資料科學家的最強清潔工:janitor 套件入門介紹

Author

lucy

在資料分析的世界裡,有一句流傳已久的名言:「資料科學家有 80% 的時間都花在資料清洗上,剩下的 20% 則是花在抱怨資料有多髒。」

如果你也常常拿到欄位名稱亂七八糟、充斥著空白行、或是重覆資料的 Excel 檔案,那麼今天介紹的這款 R 語言套件—— janitor(英文原意為工友、清潔工),絕對會成為你相見恨晚的救星!

🛠️ janitor 的起源:為了解救被 Excel 折磨的分析師

janitor 套件主要是由資料科學家 Sam Firke2016 年 左右開發並釋出。

當時,Sam Firke 在日常工作中需要處理大量來自不同部門、格式千奇百怪的 Excel 報表。他發現自己每次拿到新資料時,都在重複做幾件極度枯燥且耗時的事:修改難看的欄位名稱、刪除整行空無一物的表格、以及製作簡單的交叉檢查表。

為了拯救自己與廣大飽受「髒資料」折磨的分析師,他本著開源精神開發了 janitor。這款套件的設計哲學非常純粹——「簡單、專一、對管道符號(%>%|>)極度友好」。它不追求複雜的機器學習演算法,而是專注於在資料進入分析階段前的「第一步」,幫你把資料整理得乾乾淨淨。

安裝與載入

核心函數詳解

1. clean_names() — 欄位名稱自動整理

這是 janitor 最廣為人知的明星函數,每次讀入資料後都應該呼叫它

現實中的資料集往往有著令人頭痛的欄位名稱:中間有空格、混用大小寫、夾雜特殊符號……這些都會在後續分析中造成麻煩。clean_names() 一步到位,將所有名稱統一轉為整潔的 snake_case 格式。

library(janitor)

Attaching package: 'janitor'
The following objects are masked from 'package:stats':

    chisq.test, fisher.test
# 模擬一個欄位名稱混亂的 data.frame
df <- data.frame(
  "First Name"    = c("Alice", "Bob"),
  "age (year)"    = c(30, 25),
  "% Score 2023!" = c(88.5, 92.0)
)

head(df)
  First.Name age..year. X..Score.2023.
1      Alice         30           88.5
2        Bob         25           92.0
df_clean <- df %>% clean_names()
# 欄位名稱變成:first_name, 年齡_歲, percent_score_2023

head(df_clean)
  first_name age_year x_score_2023
1      Alice       30         88.5
2        Bob       25         92.0

預設輸出為 snake_case,也可以透過參數指定 "camelCase""UpperCamel" 等格式。特殊字元、空格、甚至部分 Unicode 字元都能正確處理。

2. remove_empty() — 移除空白列與欄

從 Excel 或外部系統匯入的資料,常常帶有完全空白的列或欄。remove_empty() 可以快速清除這些雜訊。

df %>% remove_empty("rows")   # 移除全空的列
df %>% remove_empty("cols")   # 移除全空的欄
df %>% remove_empty(c("rows", "cols"))  # 同時移除

只需一行,省去手動過濾的麻煩。

3. get_dupes() — 找出重複記錄

資料重複是清理過程中最常見的問題之一。get_dupes() 不只告訴你有沒有重複,還會把重複的列完整列出來,方便你逐筆檢查。

# 找出 name 和 date 組合重複的記錄
df %>% get_dupes(name, date)

回傳結果會多一個 dupe_count 欄位,顯示每組重複出現了幾次,非常直觀。

4. tabyl() — 整潔的頻率表

tabyl()table() 的 tidyverse 版本,輸出結果是一個整齊的 data.frame,可以直接接管道函數進行後續處理。

head(mtcars) 
                   mpg cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
# 單變數頻率表
cat("單變數頻率表\n")
單變數頻率表
mtcars %>% tabyl(cyl)
 cyl  n percent
   4 11 0.34375
   6  7 0.21875
   8 14 0.43750
# 雙變數交叉表
cat("\n雙變數交叉表\n")

雙變數交叉表
mtcars %>% tabyl(cyl, vs)
 cyl  0  1
   4  1 10
   6  3  4
   8 14  0

一行指令,頻率與百分比同時呈現,遠比 table() 更易讀。

5. adorn_* 系列 — 美化報表輸出

tabyl() 搭配 adorn_* 系列函數,能產出接近 Excel 樞紐分析表風格的報表,非常適合向非技術背景的同事或主管報告。

mtcars %>%
  tabyl(cyl, gear) %>%
  adorn_totals(c("row", "col")) %>%        # 加入加總列與欄
  adorn_percentages("col") %>%             # 轉為列百分比
  adorn_pct_formatting(digits = 1) %>%     # 格式化為 xx.x%
  adorn_ns(position = "front") %>%         # 次數在前,百分比在後
  adorn_title("combined")                  # 顯示 cyl/gear 標題
 cyl/gear           3           4          5       Total
        4  1   (6.7%)  8  (66.7%) 2  (40.0%) 11  (34.4%)
        6  2  (13.3%)  4  (33.3%) 1  (20.0%)  7  (21.9%)
        8 12  (80.0%)  0   (0.0%) 2  (40.0%) 14  (43.8%)
    Total 15 (100.0%) 12 (100.0%) 5 (100.0%) 32 (100.0%)

左上角的 cyl/gear 標題讓讀者一眼看懂列與欄的意義;次數放前面、百分比用括號包在後面,閱讀起來更自然直覺。幾行程式碼就能產出一張接近 Excel 樞紐分析表風格的摘要表,讓資料報告瞬間提升質感。

6. excel_numeric_to_date() — 修復 Excel 日期

從 Excel 匯入資料時,日期欄位有時會變成一串神秘數字(例如 44927)。這是 Excel 以「距離 1900 年 1 月 1 日的天數」儲存日期的格式,excel_numeric_to_date() 能一鍵還原成正確的日期。

excel_numeric_to_date(44927)
[1] "2023-01-01"
# [1] "2023-01-01"

這個小函數在處理從 Excel 直接匯出的原始資料時,可以幫你省下大量的除錯時間。

實戰流程:一條管道清理資料

以下示範在一個完整的資料讀取與清理流程中,如何串聯使用 janitor 的多個函數:

library(readxl)
library(janitor)
library(dplyr)
 
clean_data <- read_excel("raw_data.xlsx") %>%
  clean_names() %>%                      # 整理欄位名稱(janitor)
  remove_empty(c("rows", "cols")) %>%    # 移除空白(janitor)
  filter(!is.na(id)) %>%                 # 過濾關鍵欄位為空的列(dplyr)
  distinct() %>%                         # 移除完全重複的列(dplyr)
  remove_constant()                      # 移除所有值相同、無分析價值的欄(janitor)
 
# 確認是否還有重複的 id
clean_data %>% get_dupes(id) #(janitor)

整個清理流程清晰、可讀、可重現,完全符合 tidyverse 的精神。

小結

janitor 不是複雜的建模套件,而是一個非常實用的資料清理工具箱。它能幫助使用者快速整理欄位名稱、移除空白資料、檢查重複值,並建立乾淨的次數表與交叉表。對剛開始學 R 的人來說,janitor 可以降低資料前處理的門檻;對有經驗的分析師來說,它則能節省大量重複性工作時間。簡單來說,janitor 就是 R 裡最稱職的「資料清潔工」。

參考資料:janitor 官方 GitHubCRAN 文件 ・ Sam Firke 部落格