SAS 9.4 中具有哈希表的中位数

median with hash table in sas 9.4

提问人:mathilde 提问时间:10/20/2023 更新时间:10/21/2023 访问量:41

问:

我想用哈希表按组计算 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 小时)

SAS 哈希表 哈希码 中位数

评论


答:

2赞 Quentin 10/20/2023 #1

这不是一个好主意。您不太可能编写这样的 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 提供的功能。

1赞 Stu Sztukowski 10/20/2023 #2

与其使用哈希表来计算每个值的百分位数,不如考虑使用 或 来计算中位数,并可选择大大提高效率(链接)。 专为大数据而设计,但也是多线程的,因此请尝试两者,看看哪个性能最好。使用以下方法查看此包含 100 个变量的 10M 行表的性能:hpsummarymeansqmethod=p2hpsummarymeansqmethod=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=p2proc 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