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

SAS中存在缺失值时如何将宽数据集转换为长数据集?

SAS宽格式转长格式实现方案

先创建和你提供的结构一致的测试数据集,方便你直接运行验证:

/* 创建原始宽格式数据集 */
data wide_data;
    input LOCID Name $ Addtl_Loc_1 Addtl_Loc_2 Addtl_Loc_3;
    datalines;
1 A 2 3 5
1 B 2 . .
1 C 2 4 .
;
run;

步骤1:生成人员唯一ID(可选但推荐)

因为你提到没有人员唯一标识,这里基于Name生成自增ID(假设Name唯一,若Name重复可结合其他字段调整):

/* 提取唯一Name并生成ID */
data name_ids;
    set wide_data;
    keep Name;
run;

proc sort data=name_ids nodupkey;
    by Name;
run;

data name_ids;
    set name_ids;
    Person_ID = _N_; /* 生成自增唯一ID */
run;

/* 合并ID回原始数据集 */
data wide_data_with_id;
    merge wide_data name_ids;
    by Name;
run;

方法一:DATA步数组实现(新手友好,逻辑清晰)

用数组遍历所有地点列,逐行生成记录,同时处理空值和Gender映射:

data long_data;
    set wide_data_with_id;
    /* 定义数组,包含所有需要转成行的地点字段 */
    array locs[4] LOCID Addtl_Loc_1 Addtl_Loc_2 Addtl_Loc_3;
    
    /* 遍历数组中的每个地点值 */
    do i = 1 to dim(locs);
        Current_LOCID = locs[i];
        /* 跳过空的地点值 */
        if not missing(Current_LOCID) then do;
            /* 根据Name映射Gender */
            if Name in ('A', 'C') then Gender = 'F';
            else if Name = 'B' then Gender = 'M';
            else Gender = ''; /* 其他Name可自行补充规则 */
            
            output; /* 输出当前这条长格式记录 */
        end;
    end;
    
    /* 保留最终需要的字段,并重命名列名 */
    keep Person_ID Name Current_LOCID Gender;
    rename Current_LOCID = LOCID;
run;

代码解释:

  • array locs[4] ...:把LOCID和三个附加地点列放到一个数组里,方便批量处理
  • do i = 1 to dim(locs):循环遍历数组的每个元素,每个元素对应一个地点值
  • if not missing(Current_LOCID):过滤掉空的地点(比如B的Addtl Loc 2/3是空值,就不生成记录)
  • Gender赋值:直接根据Name的规则映射,你可以根据实际需求修改这个逻辑

方法二:PROC TRANSPOSE实现(SAS官方推荐的转置工具)

如果习惯用SAS过程步,用TRANSPOSE更简洁:

/* 转置地点列 */
proc transpose data=wide_data_with_id out=transposed_loc(drop=_name_ _label_);
    by Person_ID Name; /* 按人员分组,转置时保留这些字段 */
    var LOCID Addtl_Loc_1 Addtl_Loc_2 Addtl_Loc_3; /* 要转置的列 */
run;

/* 过滤空值并添加Gender */
data long_data_transpose;
    set transposed_loc;
    where not missing(col1); /* 去掉空地点 */
    /* 映射Gender */
    Gender = ifc(Name in ('A','C'), 'F', ifc(Name='B','M',''));
    rename col1 = LOCID; /* 把转置后的列名改成目标LOCID */
    keep Person_ID Name LOCID Gender;
run;

代码解释:

  • PROC TRANSPOSE:把指定的列(var语句里的)转成行,by语句里的字段会保留在每行中
  • drop=_name_ _label_:去掉转置自动生成的冗余字段
  • ifc函数:是SAS的条件函数,简化多分支判断,和if-else逻辑等价

验证结果

运行完上述代码后,查看long_data或long_data_transpose,就能得到你需要的长格式数据集,包含每个人员的所有地点记录,以及对应的Gender和人员唯一ID。

内容的提问来源于stack exchange,提问作者Kayleigh N

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 23:35:28