Is there a way to compute percentiles without storing values from a loop, in SAS?

569 views Asked by At

Is there a way to compute the 5th and 95th percentiles without storing all the values from a loop?

%let it=10000;
data test;
    length arrayStore$32767;
    arrayStore='';
    sum=0;
    min=99999;
    max=-99999;
    do i=1 to ⁢
        number=rand('Uniform');
        sum + number;
        if number<min then min=number;
        if number>max then max=number;
        arrayStore=catx(' ',arrayStore,round(number,0.1));
    end;
    mean=sum/&it;

    P5=0; *?;
    p95=0; *?;

    * count numbers in arrayStore;
    do j=1 to countw(arrayStore, ' ', 's');
    end;
run;

I don't think it's possible but then what would be the best option to achieve this?

Store the values in an string, sort them and find the xth postitions? Or store them in 10k numeric variables ?

I already tried to store the numbers in different records (lines) but that leads me to a 34Gb dataset which takes a long time to sort while I really only need the mean and the P2_5 and P97_5 values. I'm trying to store less values to make computing faster.

Thanks!

2

There are 2 answers

0
data _null_ On BEST ANSWER

I think you can get what you want more directly if you store the random numbers in a temporary array and use SAS descriptive statistics functions.

%let it=10000;
data test;
   call streaminit(811486001);
   array x[&it] _temporary_;
   do i=1 to &it;
      x[i] = round(rand('Uniform'),.01);
      end;
   mean = mean(of x[*]);
   p05  = pctl(5,of x[*]);
   p95  = pctl(95,of x[*]);
   put 'NOTE: ' (p:)(=);
   run;
%put NOTE: &=sysrandom;
0
Reeza On

Proc Univariate is a better method, IMO.

proc univariate data=sashelp.class noprint;
var weight;
output out=want pctlpts=2.5 97.5 PCTLPRE=P;
run;

proc print data=want;
run;