You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将大型长格式数据集转宽格式:求高效替代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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 18:07:10