R dplyr 数据整理流水线:从原始数据到干净表格
问题
分析师常常耗费大量时间编写重复的 R 循环来清洗数据集。结果是脚本脆弱、列结构前后不一致,而且每次有新文件到来时迭代都很缓慢。
加剧
手工步骤会层层堆叠:选错列、变换顺序错误,或者忘记区分 factor 与 character。每一次失误都意味着重跑流程,并且有把错误指标传递到下游仪表盘的风险。
解决思路
采用一套统一的 dplyr 流水线,让逻辑贴近 SQL,同时保持每一步变换都可读可追踪。下面这些动词覆盖了列选择、行过滤、新特征构造、聚合汇总、排序以及安全的连接操作,保证数据在建模或可视化前已经整洁有序。
核心流水线示例
library(dplyr)
clean_sales <- raw_sales %>%
mutate(
region = as.character(region), # avoid accidental factor levels
revenue = price * quantity
) %>%
filter(!is.na(revenue), revenue > 0) %>%
select(order_id, region, revenue, channel, order_date) %>%
arrange(desc(revenue)) %>%
group_by(region, channel) %>%
summarise(
orders = n(),
revenue = sum(revenue),
avg_order = mean(revenue),
.groups = "drop"
)dplyr 动词与 SQL 等价关系
| dplyr verb | 用途 | SQL 类比 | 速记说明 |
|---|---|---|---|
select() | 保留或重命名列 | SELECT col1, col2 | 使用 everything() 可快速重排列顺序。 |
filter() | 行子集筛选 | WHERE condition | 结合 %in% 处理多值匹配。 |
mutate() | 新增 / 变换列 | SELECT col1, col2*2 AS col2x | 使用 if_else() 保持返回类型稳定。 |
summarise() + group_by() | 分组统计指标 | GROUP BY ... | 添加 .groups = "drop" 以取消分组。 |
arrange() | 对行排序 | ORDER BY | 使用 desc() 实现降序。 |
left_join() | 用维表补充字段 | LEFT JOIN | 保持连接键的类型一致(character 与 factor 不要混用)。 |
bind_rows() / bind_cols() | 纵向堆叠或横向拼接表 | UNION ALL / 列拼接 | 纵向堆叠前确保表结构一致。 |
Join 与 bind 的一目了然对比
# Join:根据维表补充列
sales_with_regions <- sales %>%
left_join(region_lookup, by = "region_id")
# Bind:堆叠相同表结构
all_sales <- bind_rows(sales_2023, sales_2024)避免 factor 与编码陷阱
- 在做 join 之前,将标识类字段转换为
character,避免因水平不匹配而出错。 - 如果从 CSV 读取时被隐式解析成了 factor,可用
mutate(across(where(is.factor), as.character))批量转换。 - 在分组前用
stringr::str_trim和tolower统一文本格式,避免同一类别被拆成多个名称。
快速上手模板
prep_data <- function(df) {
df %>%
mutate(across(where(is.factor), as.character)) %>%
filter(!is.na(key_id)) %>%
distinct() %>%
select(key_id, everything())
}导出前检查清单
- 已显式选择并排好列顺序。
- 关键 join 使用了类型一致的键,并在需要时用清晰的后缀区分(如
suffix = c(".src", ".lkp"))。 - 汇总步骤已通过
.groups = "drop"解除分组,避免后续步骤行为异常。 - 输出只包含干净、易读的字段,能够直接用于绘图或建模。
相关指南
- 从零构建整洁表: Creating Dataframe in R
- 分组并做汇总: Grouping in R with group_by()
- 绘图前的准备: R ggplot2 Quickstart