TTT
TTT

Reputation: 4434

SAS proc univariate for many variables by macro or array

This should be an easy question, but I didn't figure out... I want to get mean and median of many variables by proc univariate as below. It's really time consuming to manually add M_ for mean and MD_ for median to all variables. I am wondering if there any simple approach, such as array to do so? Thanks a lot!

Code:

data old;
input year type A1 A2 A3 A4 A5;
datalines;
2000    1   1   2   3   4   5
2000    1   2   3   4   5   6
2000    2   3   4   5   6   7
2000    2   4   5   6   7   8
2001    1   5   6   7   8   9
2001    1   6   7   8   9   10
2001    1   7   8   9   10  11
2001    2   8   9   10  11  12
2001    2   9   10  11  12  13
2001    2   10  11  12  13  14
2002    1   11  12  13  14  15
2002    1   12  13  14  15  16
2002    1   13  14  15  16  17
2002    2   14  15  16  17  18
2002    2   15  16  17  18  19
2002    2   16  17  18  19  20
run;

proc univariate data=old noprint;
    var A1 A2 A3 A4 A5;
    by year type;
    output out=new
    mean=M_A1 M_A2 M_A3 M_A4 M_A5
    median=MD_A1 MD_A2 MD_A3 MD_A4 MD_A5;
run;

Expected demo Code:

%let varlist = A1 A2 A3 A4 A5; 
array vars (*) &varlist;
proc univariate data=old noprint;
    var &vars(*);
    by year type;
    output out=new
    mean=M_&vars(*)
    median=MD_&vars(*);
run;

correct code by using proc sql

%macro uni;
%let varlist='A1','A2','A3','A4','A5';
%let vars=A1 A2 A3 A4 A5;
proc sql;
select cats('M_',name) into :meannamelist separated by ' '
 from dictionary.columns
 where libname='WORK' and memname='OLD' and name in (&varlist);
select cats('MD_',name) into :mediannamelist separated by ' '
 from dictionary.columns
 where libname='WORK' and memname='OLD' and name in (&varlist);
quit;

proc univariate data=old;
    var &vars;
    by year type;
    output out=new
    mean=&meannamelist
    median=&mediannamelist;
run;
%mend uni;
options mprint;
%uni;

Upvotes: 1

Views: 4183

Answers (3)

Zfunk
Zfunk

Reputation: 1193

One way of completing your code is to loop through a list:

proc univariate data=old noprint;

  var

  %let varlist1 = A1 A2 A3 A4 A5;
  %let count_number1=1;
  %let value1=%scan(&varlist1.,&count_number1.); 
  %do %while(&value1. NE %str());

   &value1.

   %let count_number1=%eval(&count_number1.+1);
   %let value1=%scan(&varlist1.,&count_number1.);
  %end;
   ;

  by year type;
  output out=new
  mean=

   %let varlist2 = A1 A2 A3 A4 A5;
   %let count_number2=1;
   %let value2=%scan(&varlist2.,&count_number2.); 
    %do %while(&value2. NE %str());

       M_&value2. 

       %let count_number2=%eval(&count_number2.+1);
       %let value2=%scan(&varlist2.,&count_number2.);
     %end;
    ;
run;

Upvotes: 1

Joe
Joe

Reputation: 63424

Another option is to create these lists in PROC SQL.

%let varlist=A1,A2,A3,A4,A5;
proc sql;
select cats('M_',name) into :meannamelist separated by ' '
 from dictionary.columns
 where libname='WORK' and memname='OLD' and name in (&varlist);
select cats('MD_',name) into :mediannamelist separated by ' '
 from dictionary.columns
 where libname='WORK' and memname='OLD' and name in (&varlist);
quit;

proc univariate etc.;
mean &meannamelist;
median &mediannamelist;
run;

Upvotes: 2

Joe
Joe

Reputation: 63424

If you can use PROC MEANS to obtain the needed stats, do that; it has an autoname option on the output statement that does approximately what you're asking for. Both mean and median are available in PROC MEANS.

If not, you might look to ods output to simplify things.

Upvotes: 0

Related Questions