提问人:mathilde 提问时间:10/20/2023 更新时间:10/21/2023 访问量:41
SAS 9.4 中具有哈希表的中位数
median with hash table in sas 9.4
问:
我想用哈希表按组计算 100 个变量的中位数。
我发现它用于计算 sashelp.cars 上发票的中位数,但是如果我想按品牌和型号进行中位数,例如,我该如何调整它?
data percentiles ;
keep percentile Invoice ;
format percentile percent5.;
dcl hash ptiles (dataset: "sashelp.cars(where=(Invoice gt 0))",multidata:"Y",ordered:"A");
ptiles.definekey("Invoice");
ptiles.definedone();
declare hiter iterP ("ptiles");
array _ptiles(6) _temporary_ (.5 .05 .1 .25 .75 .95);
call sortn(of _ptiles(*));
num_items=ptiles.num_items;
do i=1 to dim (_ptiles);
percentile=_ptiles(i);
do while (Counter lt percentile*num_items);
Counter+1;
iterP.next();
end;
output;
end;
stop;
set sashelp.cars;
run;
事实上,在我的卷轴数据中,我想计算 100 个变量的中位数。 实际上,我用 proc 单变量来做这件事,但它太长了(>12 小时)
答:
这不是一个好主意。您不太可能编写这样的 DATA 步骤,该步骤将比 PROC MEANS 更快:
proc means data=sashelp.cars p5 p10 p25 p50 p75 p95;
var Invoice ;
run ;
注意 PROC MEANS 可能比 PROC UNIVARIATE 快得多,因为它执行的工作更少。您也可以尝试简单的 SQL 步骤。
如果 UNIVARIATE 步骤花费了很长时间,则可能有很多数据。在我的 PC 上,我运行了您的 DATA 步骤和 PROC MEANS 作为输入:
data cars ;
set sashelp.cars ;
do i=1 to 100000 ;
output ;
end ;
run ;
您的 DATA 步骤花了 8 秒,PROC MEANS 花了 2 秒。
另请注意,您的 DATA 步骤使用非常简单的方法来计算百分位数,而不是处理关系。如果比较步骤的结果,它们将与 PROC UNIVARIATE 或 PROC MEANS 的结果不匹配。
使用SAS时,需要考虑许多效率因素(数据在哪里?是否涉及网络?等)但通常,您不希望手动编写 SAS 提供的功能。
与其使用哈希表来计算每个值的百分位数,不如考虑使用 或 来计算中位数,并可选择大大提高效率(链接)。 专为大数据而设计,但也是多线程的,因此请尝试两者,看看哪个性能最好。使用以下方法查看此包含 100 个变量的 10M 行表的性能:hpsummary
means
qmethod=p2
hpsummary
means
qmethod=p2
data have;
array var[100];
do i = 1 to 10000000;
do j = 1 to 100;
var[j] = rand('normal');
end;
output;
end;
run;
proc hpsummary data=have qmethod=p2;
var var:;
output out=want
median=;
quit;
在具有 16GB RAM 的机器上,使用 4 个线程花费了 1 分 5 秒。
NOTE: There were 10000000 observations read from the data set WORK.HAVE.
NOTE: The data set WORK.WANT has 1 observations and 102 variables.
NOTE: PROCEDURE HPSUMMARY used (Total process time):
real time 1:05.69
cpu time 4:05.92
您还可以与以下功能一起使用:qmethod=p2
proc means
proc means data=have qmethod=p2 noprint;
var var:;
output out=want
median=;
quit;
NOTE: There were 10000000 observations read from the data set WORK.HAVE.
NOTE: The data set WORK.WANT has 1 observations and 102 variables.
NOTE: PROCEDURE MEANS used (Total process time):
real time 46.33 seconds
cpu time 3:05.50
评论