%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;