SAS如何实现按ID分组每行统计后续6行Number值总和
SAS实现方案
前置要求
先确保原始数据集已经按ID、Months升序排序,未排序的话先执行以下代码:
proc sort data=你的原始数据集名; by ID Months; run;
方案1:用PROC EXPAND实现(需SAS/ETS模块,代码最简洁)
适合有权限使用ETS模块的场景,不需要手动写循环逻辑:
proc expand data=你的原始数据集名 out=输出数据集名 method=none; by ID; /* 取当前行之后6个观测的Number求和,不足6个自动赋值为缺失 */ convert Number = Sum_Next_6Number / transformout=(lead 1 lead 2 lead 3 lead 4 lead 5 lead 6 sum); run;
方案2:DATA步实现(全版本SAS通用,无模块依赖)
没有ETS模块可以用双循环+临时数组的通用方法实现,数组大小可以根据单个ID下的最大观测数调整:
data 输出数据集名; retain ID Months Number Sum_Next_6Number; /* 临时数组存当前ID下的所有Number值,大小可按需调整 */ array num_arr[1000] _temporary_; /* 第一次遍历:把当前ID的所有Number存入数组,记录该ID总观测数 */ do n = 1 by 1 until(last.ID); set 你的原始数据集名; by ID; num_arr[n] = Number; end; /* 第二次遍历:逐行计算后6个观测的和 */ do i = 1 to n; set 你的原始数据集名; by ID; if i + 6 <= n then do; Sum_Next_6Number = sum(num_arr[i+1], num_arr[i+2], num_arr[i+3], num_arr[i+4], num_arr[i+5], num_arr[i+6]); end; else do; Sum_Next_6Number = .; /* SAS原生缺失值对应需求中的NaN */ end; output; end; /* 清空数组,避免不同ID之间数据干扰 */ call missing(of num_arr[*]); run;
说明
两种方案都会保留原始数据集的全部字段,新字段Sum_Next_6Number会自动追加到输出数据集中,只需把代码里的你的原始数据集名、输出数据集名替换为实际的数据集名称即可。
内容的提问来源于stack exchange,提问作者Deniz
相关产品推荐
相关产品推荐

