如何使用dplyr结合rep实现频次型存储数据框的优雅展开
适配dplyr生态的简洁实现方案
完全不需要逐行循环拼接,搭配tidyr(同属tidyverse核心生态)的原生函数即可完成,且天然支持多分类维度的扩展,核心用到两个函数:
pivot_longer():将宽表存储的计数列转换为长表,自动保留其余所有分类维度列uncount():按指定的计数值,将当前行重复对应次数,直接完成明细行展开
完整可运行代码
library(dplyr) library(tidyr) df_expanded3 <- df %>% # 将宽表的计数列转为长格式 pivot_longer( # 多维度场景下可灵活指定范围:比如固定保留若干分类列、其余全部作为计数列时,可写为 cols = -c(分类列1, 分类列2) cols = c(disease, no_disease), names_to = "disease_status", values_to = "n" ) %>% # 将原列名映射为对应的0/1患病状态 mutate(disease_status = ifelse(disease_status == "disease", 1L, 0L)) %>% # 按计数值n重复对应行数,完成展开 uncount(n)
结果校验
生成的结果和你之前循环拼接的版本完全一致:
all.equal(df_expanded3, df_expanded2) # 返回 TRUE 即说明结果无差异
方案优势
- 无冗余循环逻辑,全程使用管道链式操作,完全符合dplyr的使用习惯
- 扩展性极强:新增任意维度的分类列(例如年龄组、性别、研究地区)时,代码逻辑完全不需要修改,只要确保计数列被纳入
pivot_longer()的处理范围即可 - 性能表现远优于逐行
bind_rows的循环实现,uncount()为底层向量化实现,处理大计数规模的数据时速度提升会非常明显
内容的提问来源于stack exchange,提问作者dfrankow
相关产品推荐
相关产品推荐

