如何用DO循环替代PROC TRANSPOSE处理SAS带表头的长/宽数据
不用PROC TRANSPOSE,用DO循环实现SAS数据转置
一、长格式数据转宽格式(带分隔表头的数据块)
需求说明
长格式CSV按数据块划分,每个块开头是包含SiteID、AQS、Code的表头行,块内是3行数据:分别对应Max、MinSaleValue、Count的变量值。最终需要生成宽格式数据集,每行包含SiteID、AQS、Code以及这三个变量的数值。
解决方案代码
data InputDS.WideFromLong; infile RawData('Long Data.csv') dlm='092C'x dsd truncover firstobs=7; length SiteID $20 AQS $20 Code $20 Max MinSaleValue Count 8; retain SiteID AQS Code; /* 跨数据行保留表头变量值 */ input varname $ value; /* 读取每行的变量名与对应值 */ /* 识别并处理表头行 */ if varname = 'SiteID' then do; SiteID = value; input AQS Code; /* 读取表头行剩余两个字段 */ delete; /* 表头行仅更新变量,不输出 */ end; /* 将不同变量名的数值映射到目标变量 */ select(varname); when('Max') Max = value; when('MinSaleValue') MinSaleValue = value; when('Count') Count = value; end; /* 读取完当前块最后一个变量时,输出完整宽格式记录 */ if varname = 'Count' then output; run;
代码说明
RETAIN语句确保数据块内的所有数据行都能关联到同一组SiteID、AQS、Code值。- 通过判断
varname识别表头行,更新保留变量后跳过输出,避免表头混入数据。 - 用
SELECT语句匹配变量名赋值,当读取到Count行时,说明当前块的三个变量已全部读取,输出一条完整的宽格式记录。
二、宽格式数据转长格式(含200组重复变量)
需求说明
宽格式CSV每行包含SiteID、AQS、Code,后续有200组MaxN、MinN、CountN列(N从1到200)。需要转成长格式,每行对应一组Max、Min、Count值,并关联对应的SiteID、AQS、Code。
解决方案代码
/* 读取宽格式数据集,确保所有变量加载完整 */ data InputDS.WideData; infile RawData('Wide Data.csv') dlm=',' dsd truncover firstobs=6; input SiteID $ AQS $ Code $ Max1-Max200 Min1-Min200 Count1-Count200; run; /* 数组+DO循环转长格式 */ data InputDS.LongFromWide; set InputDS.WideData; length GroupNum 3; /* 定义数组对应三组重复变量 */ array max_arr[200] Max1-Max200; array min_arr[200] Min1-Min200; array count_arr[200] Count1-Count200; /* 遍历200组变量,生成长格式记录 */ do GroupNum = 1 to 200; Max = max_arr[GroupNum]; MinSaleValue = min_arr[GroupNum]; Count = count_arr[GroupNum]; /* 跳过全缺失的无效组 */ if not(missing(Max) and missing(MinSaleValue) and missing(Count)) then output; end; /* 保留所需变量,删除原宽格式的数组变量 */ keep SiteID AQS Code GroupNum Max MinSaleValue Count; run;
代码说明
- 读取宽数据时,利用SAS变量列表简化写法,一次性加载所有200组重复变量,避免遗漏。
- 定义三个数组分别对应
MaxN、MinN、CountN系列,通过DO循环遍历1到200,每次将数组值赋值给长格式变量并输出记录。 - 增加缺失值判断,过滤无数据的组,减少无效记录。
内容的提问来源于stack exchange,提问作者glico
相关产品推荐
相关产品推荐

