在資料分析的世界裡,有一句流傳已久的名言:「資料科學家有 80% 的時間都花在資料清洗上,剩下的 20% 則是花在抱怨資料有多髒。」
如果你也常常拿到欄位名稱亂七八糟、充斥著空白行、或是重覆資料的 Excel 檔案,那麼今天介紹的這款 R 語言套件—— janitor (英文原意為工友、清潔工),絕對會成為你相見恨晚的救星!
🛠️ janitor 的起源:為了解救被 Excel 折磨的分析師
janitor 套件主要是由資料科學家 Sam Firke 於 2016 年 左右開發並釋出。
當時,Sam Firke 在日常工作中需要處理大量來自不同部門、格式千奇百怪的 Excel 報表。他發現自己每次拿到新資料時,都在重複做幾件極度枯燥且耗時的事:修改難看的欄位名稱、刪除整行空無一物的表格、以及製作簡單的交叉檢查表。
為了拯救自己與廣大飽受「髒資料」折磨的分析師,他本著開源精神開發了 janitor。這款套件的設計哲學非常純粹——「簡單、專一、對管道符號(%>% 或 |>)極度友好」 。它不追求複雜的機器學習演算法,而是專注於在資料進入分析階段前的「第一步」,幫你把資料整理得乾乾淨淨。
核心函數詳解
1. clean_names() — 欄位名稱自動整理
這是 janitor 最廣為人知的明星函數,每次讀入資料後都應該呼叫它 。
現實中的資料集往往有著令人頭痛的欄位名稱:中間有空格、混用大小寫、夾雜特殊符號……這些都會在後續分析中造成麻煩。clean_names() 一步到位,將所有名稱統一轉為整潔的 snake_case 格式。
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,可以直接接管道函數進行後續處理。
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
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 )
這個小函數在處理從 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 官方 GitHub ・ CRAN 文件 ・ Sam Firke 部落格