Reputation: 4434
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
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
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
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