将大型长格式数据集转宽格式:求高效替代reshape()的方法
高效实现长格式转宽格式(大数据集适配)
原始长格式数据:
df <- structure(list(Disease = c("heart failure", "Hypertension", "cancer", "heart failure"), Patient_Id = c(1L, 1L, 2L, 2L)), class = "data.frame", row.names = c(NA, -4L))
目标宽格式数据:
df1 <- structure(list(Patient_ID = 1:2, heart.failure = c(1L, 1L), Hypertension = 1:0, cancer = 0:1), class = "data.frame", row.names = c(NA, -2L ))
针对大数据集,base包的reshape()函数效率不足,推荐以下几种更快的解决方案:
1. 使用data.table包(最优性能)
data.table的dcast()函数基于C语言实现,处理超大规模数据集时速度优势明显:
library(data.table) # 转换为data.table对象 setDT(df) # 直接转宽,自动统计疾病出现次数,缺失值填充为0 df_wide <- dcast(df, Patient_Id ~ Disease, fun.aggregate = length, fill = 0) # 调整列名匹配目标格式 setnames(df_wide, gsub(" ", ".", names(df_wide))) setnames(df_wide, "Patient_Id", "Patient_ID")
2. 使用tidyr + dplyr(tidyverse生态)
tidyr的pivot_wider()经过性能优化,代码简洁易读:
library(tidyr) library(dplyr) df_wide <- df %>% # 标记每行对应疾病为1 mutate(value = 1) %>% # 转宽格式,缺失值填充为0 pivot_wider( id_cols = Patient_Id, names_from = Disease, values_from = value, values_fill = 0 ) %>% # 替换列名中的空格为点 rename_with(~gsub(" ", ".", .x), -Patient_Id) %>% # 重命名患者ID列 rename(Patient_ID = Patient_Id)
3. 使用fastDummies包(快速生成哑变量)
专门用于生成哑变量的工具包,适合这类分类变量转宽的场景:
library(fastDummies) df_wide <- df %>% # 生成疾病对应的哑变量列 dummy_cols(select_columns = "Disease", remove_selected_columns = TRUE) %>% # 按患者分组,取最大值确保同一疾病只标记1次 group_by(Patient_Id) %>% summarise(across(everything(), max)) %>% # 去掉列名前缀 rename_with(~gsub("Disease_", "", .x)) %>% # 重命名患者ID列 rename(Patient_ID = Patient_Id)
以上三种方法的处理速度都远优于reshape(),其中data.table的方案在百万级以上数据集的场景下表现最佳。
内容的提问来源于stack exchange,提问作者Jamie
相关产品推荐
相关产品推荐

