R语言如何将诊断码文本列转换为二进制标识宽表
实现方案
方案1:Python Pandas 实现(适配超大数据集优化版)
该方案做了内存优化,可支持千万级以内的数据集处理:
- 第一步:按需加载列减少内存占用
import pandas as pd import numpy as np # 仅加载人员ID和99个诊断码列,假设诊断码列命名为diag_code_1到diag_code_99 use_cols = ['person_id'] + [f'diag_code_{i}' for i in range(1,100)] df = pd.read_csv('你的数据集路径.csv', usecols=use_cols, dtype=str)
- 第二步:格式转换生成二进制标记列
# 宽表转长表,过滤空诊断码 df_long = df.melt(id_vars='person_id', value_name='diag_code').dropna(subset=['diag_code']) # 去重避免同一人员同一诊断码重复计数 df_long = df_long.drop_duplicates(subset=['person_id', 'diag_code']) # 新增存在标记 df_long['flag'] = 1 # 长表转回宽表,缺失值填0,用int8类型大幅降低内存占用 df_result = df_long.pivot(index='person_id', columns='diag_code', values='flag').fillna(0).astype('int8').reset_index()
- 超内存优化:如果数据集超出本地内存,可给
read_csv添加chunksize参数分块迭代处理,每块处理完成后保存中间结果,最后合并所有中间结果即可。
方案2:R 实现
如果习惯用R处理医疗类数据集,可通过tidyverse套件实现:
library(tidyverse) # 按需加载列 df <- read_csv("你的数据集路径.csv", col_select = c(person_id, starts_with("diag_code_"))) df_result <- df %>% # 宽转长,自动去除空诊断码 pivot_longer(cols = -person_id, values_to = "diag_code", values_drop_na = T) %>% # 人员+诊断码去重 distinct(person_id, diag_code) %>% mutate(flag = 1) %>% # 长转宽,缺失值填0 pivot_wider(names_from = diag_code, values_from = flag, values_fill = 0)
方案3:亿级以上集群数据集SQL实现
如果数据存储在数仓中,可直接用SQL处理避免数据导出导入损耗:
-- 先得到人员和对应诊断码的去重结果 WITH distinct_diag AS ( SELECT person_id, diag_code FROM ( SELECT person_id, diag_code_1 AS diag_code FROM your_table UNION ALL SELECT person_id, diag_code_2 AS diag_code FROM your_table -- 剩余97个诊断码列依次补充UNION ALL语句 ... SELECT person_id, diag_code_99 AS diag_code FROM your_table ) t WHERE diag_code IS NOT NULL GROUP BY person_id, diag_code ) -- 行转列得到最终结果,也可替换为对应数仓自带的PIVOT语法简化代码 SELECT person_id, MAX(CASE WHEN diag_code = 'E11' THEN 1 ELSE 0 END) AS E11, MAX(CASE WHEN diag_code = 'I10' THEN 1 ELSE 0 END) AS I10 -- 剩余诊断码依次补充CASE语句即可 ... FROM distinct_diag GROUP BY person_id;
内容的提问来源于stack exchange,提问作者imogenrae
相关产品推荐
相关产品推荐

