Henry Sumner
Henry Sumner

Reputation: 21

How do I create a SAS data view from an 'Out=' option?

I have a process flow in SAS Enterprise Guide which is comprised mainly of Data views rather than tables, for the sake of storage in the work library.

The problem is that I need to calculate percentiles (using proc univariate) from one of the data views and left join this to the final table (shown in the screenshot of my process flow).

enter image description here

Is there any way that I can specify the outfile in the univariate procedure as being a data view, so that the procedure doesn't calculate everything prior to it in the flow? When the percentiles are left joined to the final table, the flow is calculated again so I'm effectively doubling my processing time.

Please find the code for the univariate procedure below

proc univariate data=WORK.QUERY_FOR_SGFIX noprint;
var CSA_Price;
by product_id;

output out= work.CSA_Percentiles_Prod

pctlpre= P
pctlpts= 40 to 60 by 10;

run;

Upvotes: 0

Views: 262

Answers (1)

user667489
user667489

Reputation: 9569

In SAS, my understanding is that procs such as proc univariate cannot generally produce views as output. The only workaround I can think of would be for you to replicate the proc logic within a data step and produce a view from the data step. You could do this e.g. by transposing your variables into temporary arrays and using the pctl function.

Here's a simple example:

data example /view = example;
  array _height[19]; /*Number of rows in sashelp.class dataset*/

  /*Populate array*/
  do _n_ = 1 by 1 until(eof);
    set sashelp.class end = eof;
    _height[_n_] = height;
  end;

  /*Calculate quantiles*/
  array quantiles[3] q40 q50 q60;
  array points[3] (40 50 60);
  do i = 1 to 3;
    quantiles[i] = pctl(points[i], of _height{*});
  end;

  /*Keep only the quantiles we calculated*/
  keep q40--q60;
run;

With a bit more work, you could also make this approach return percentiles for individual by groups rather than for the whole dataset at once. You would need to write a double-DOW loop to do this, e.g.:

data example;
  array _height[19];
  array quantiles[3] q40 q50 q60;
  array points[3] _temporary_ (40 50 60);

  /*Clear heights array between by groups*/
  call missing(of _height[*]);

  /*Populate heights array*/
  do _n_ = 1 by 1 until(last.sex);
    set class end = eof;
    by sex;
    _height[_n_] = height;
  end;

  /*Calculate quantiles*/
  do i = 1 to 3;
    quantiles[i] = pctl(points[i], of _height{*});
  end;

  /* Output all rows from input dataset, with by-group quantiles attached*/
  do _n_ = 1 to _n_;
    set class;
    output;
  end;
  keep name sex q40--q60;
run;

Upvotes: 0

Related Questions