%macro tranmed (data=, /* input data set */
var=, /* variable list to calculate */
/* the median from */
pctldef=5, /* initialize the percentile */
/* definition for PROC */
/* UNIVARIATE */
uniqueid=, /* unique identifier */
out=); /* output data set */
/* Rearrange the data to create a data set that */
/* contains one observation for each variable in */
/* VAR. Each observation contains values for the BY */
/* variable the identifier, and for one variable in */
/* VAR. */
proc transpose data=&data(keep=&var &uniqueid) out=transp;
by &uniqueid notsorted;
run;
/* Calculate the median for each BY group in the */
/* data set that PROC TRANSPOSE created. Store the */
/* output in MED1. This data set, like the original */
/* data set, now contains one observation for each */
/* value of UNIQUEID. The NOTSORTED option indicates */
/* that all observations with the same BY value are */
/* grouped together but that the groups are not in */
/* any particular order. In this macro, where we */
/* assume that there is only one observation in each */
/* BY group, NOTSORTED lets you take advantage of BY */
/* processing without sorting the data. */
proc univariate data=transp pctldef=&pctldef noprint;
by &uniqueid notsorted;
output out=med1 median=median;
run;
/* Merge the input and output data sets. A one-to-one*/
/* merge is appropriate because both data sets are */
/* sorted by UNIQUEID and both have only one */
/* observation for each value of UNIQUEID. */
data &out;
merge &data med1;
run;
%mend tranmed;