SAS PROC 中的累计月度百分位计算 SQL
Accumulated Monthly Percentile Calculation in SAS PROC SQL
我有一个 table 非常类似于以下格式:
ID | Month_ID | Param1 | Param2
1 | 1 | 5 | 10
1 | 1 | 6 | 12
1 | 2 | 4 | 9
1 | 2 | 8 | 15
2 | 1 | 3 | 17
2 | 1 | 5 | 12
2 | 2 | 3 | 11
2 | 2 | 6 | 10
我需要通过 ID 和 month_id 计算 param1 和 param2 的几个百分位数(50、75、85、90、95),但是对于每个月,我都需要包括上一个的所有数据个月(因此 month_id=2 将使用来自 month_id=1 和 month_id=2 的数据计算 param1 和 param2 的百分位数)。我试过使用 proc univariate
,但我只能弄清楚如何使用以下代码为每个月获取它:
proc univariate data=table noprint;
by ID Month_ID NOTSORTED;
var param1 param2;
output out=Pctls pctlpts = 50 75 85 90 95
pctlpre = param1_ param2_
pctlname = pct50 pct75 pct85 pct90 pct95;
run;
有谁知道通过累积月份来计算这些百分位数的方法吗?提前致谢!
我想不出直接在 proc univariate 中执行此操作的方法,但我可能会按如下方式扩展和重新组合数据:
*dummy data ;
data input ;
do ID=1 to 2 ;
do month_id=1 to 12 ;
parm1=int(ranuni(1)*100) ;
parm2=int(ranuni(1)*100) ;
output ;
end ;
end ;
run ;
data expand ;
set input ;
do group=12 to 1 by -1 ;
if month_id le group then output ;
end ;
run ;
这将为您提供一个组变量,其中 group=1 仅包含 month1,group=2 包含 month1 和 month2 等。
一种方法是通过创建参数的累积版本来预处理数据。此代码假定整个 table 已按您的示例中的顺序排序。它应该像 SQL group by
一样工作,它也在累积:
data accum_table;
set table;
by ID Month_ID;
if first.ID then call missing (Accum1, Accum2);
Accum1+Param1;
Accum2+Param2;
if last.Month_ID then output;
run;
这应该适用于自定义月份范围(尽管假设每个 ID 的月份都在最小值和最大值之间):
具有不同月份范围的虚拟数据:
data input ;
do ID=1 to 2 ;
do month_id=3+ID to 20-ID*2 ;
parm1=int(ranuni(1)*100) ;
parm2=int(ranuni(1)*100) ;
output ;
end ;
end ;
run ;
确定每个 ID 组的最小和最大月份:
proc sql ;
create table range as
select *, min(month_id) as minmonth, max(month_id) as maxmonth
from input
group by ID
order by ID, month_id
;quit ;
将每个月输出到适当的组中:
data output ;
set range ;
by ID ;
do group=month_id to maxmonth ;
output ;
end ;
run;
我有一个 table 非常类似于以下格式:
ID | Month_ID | Param1 | Param2
1 | 1 | 5 | 10
1 | 1 | 6 | 12
1 | 2 | 4 | 9
1 | 2 | 8 | 15
2 | 1 | 3 | 17
2 | 1 | 5 | 12
2 | 2 | 3 | 11
2 | 2 | 6 | 10
我需要通过 ID 和 month_id 计算 param1 和 param2 的几个百分位数(50、75、85、90、95),但是对于每个月,我都需要包括上一个的所有数据个月(因此 month_id=2 将使用来自 month_id=1 和 month_id=2 的数据计算 param1 和 param2 的百分位数)。我试过使用 proc univariate
,但我只能弄清楚如何使用以下代码为每个月获取它:
proc univariate data=table noprint;
by ID Month_ID NOTSORTED;
var param1 param2;
output out=Pctls pctlpts = 50 75 85 90 95
pctlpre = param1_ param2_
pctlname = pct50 pct75 pct85 pct90 pct95;
run;
有谁知道通过累积月份来计算这些百分位数的方法吗?提前致谢!
我想不出直接在 proc univariate 中执行此操作的方法,但我可能会按如下方式扩展和重新组合数据:
*dummy data ;
data input ;
do ID=1 to 2 ;
do month_id=1 to 12 ;
parm1=int(ranuni(1)*100) ;
parm2=int(ranuni(1)*100) ;
output ;
end ;
end ;
run ;
data expand ;
set input ;
do group=12 to 1 by -1 ;
if month_id le group then output ;
end ;
run ;
这将为您提供一个组变量,其中 group=1 仅包含 month1,group=2 包含 month1 和 month2 等。
一种方法是通过创建参数的累积版本来预处理数据。此代码假定整个 table 已按您的示例中的顺序排序。它应该像 SQL group by
一样工作,它也在累积:
data accum_table;
set table;
by ID Month_ID;
if first.ID then call missing (Accum1, Accum2);
Accum1+Param1;
Accum2+Param2;
if last.Month_ID then output;
run;
这应该适用于自定义月份范围(尽管假设每个 ID 的月份都在最小值和最大值之间):
具有不同月份范围的虚拟数据:
data input ;
do ID=1 to 2 ;
do month_id=3+ID to 20-ID*2 ;
parm1=int(ranuni(1)*100) ;
parm2=int(ranuni(1)*100) ;
output ;
end ;
end ;
run ;
确定每个 ID 组的最小和最大月份:
proc sql ;
create table range as
select *, min(month_id) as minmonth, max(month_id) as maxmonth
from input
group by ID
order by ID, month_id
;quit ;
将每个月输出到适当的组中:
data output ;
set range ;
by ID ;
do group=month_id to maxmonth ;
output ;
end ;
run;