Hi:
Using macro variables is not required for this task, if your data is as you describe it. PROC REPORT has a usage of "ACROSS" that turns variable values into columns. Just as you have DISPLAY in your code below, you would define a usage of ACROSS for day and date. Your data (as shown) is long and skinny. It looks like you have a variable called DAY, whose possible values are "Screening", "Day2", "Day4", etc. So in your DEFINE statement, you would have only 1 DEFINE statement -- your DEFINE statement lists the variable -- NOT the variable values:
[pre]
define day / across order=data;
[/pre]
This way, PROC REPORT knows to make one unique column for every value of the DAY variable. You need order=data because the value 'Screening' needs to appear in the columns before the value 'Day 2'. Since you have a variable called DATE that already contains the dates you want, there is no problem with nesting the DATE variable under the DAY variable. Finally, you'd put RESULT into the mix. You indicate this nesting by using a comma in the COLUMN statement:
[pre]
column patient test result,day,date;
[/pre]
I'd list RESULT first, so that a single column header for this variable will span over all the days/dates. Or, if you blank out the header, then ODS HTML, RTF or PDF would suppress the blank line if it's at the top of all the nested column headers.
Then since you want each patient treated separately, that's an argument for using a BY PATIENT statement inside PROC REPORT. This will have the side effect of putting a header or caption above each table of: Patient=101, etc. If you don't want to see the byline information, you can turn if off with a SAS system option.
The other side effect of BY group processing would be for every patient to be on a separate page. If you have more tests for each patient, then this may be OK (for every patient to start on a separate page). If you want to have multiple patient tables on a page (assuming their tables are small enough), then you can investigate the STARTPAGE=NO option of the ODS RTF destination.
My suggestion is that you read more in the documentation about PROC REPORT and look at more examples of ACROSS usage. You can also search for user papers about PROC REPORT. In addition, Tech Support can help you if you run into snags.
The program below uses the data you gave as a sample. A patient could have more test results, and, as long as the test names are unique, each new test would be on a report row by itself. However, if one patient had 2 hemoglobin tests on the same days, then this approach might not work. You might need to manually transpose the long, skinny data into wide data, with a column for every date. But this may get you started.
cynthia
[pre]
data pt_data;
length patient 8 test $15 day $10 result 8 date 8;
infile datalines;
input patient test $ day $ result date : date9.;
return;
datalines;
101 monocytes screening 64 13MAR2008
101 monocytes day2 67 15MAR2008
101 monocytes day4 72 17MAR2008
101 monocytes day7 71 20MAR2008
101 hemoglobin screening 107 13MAR2008
101 hemoglobin day2 120 15MAR2008
101 hemoglobin day4 118 17MAR2008
101 hemoglobin day7 125 20MAR2008
102 monocytes screening 80 14APR2008
102 monocytes day2 73 18APR2008
102 monocytes day4 75 20APR2008
102 monocytes day7 81 23APR2008
102 hemoglobin screening 112 14APR2008
102 hemoglobin day2 119 18APR2008
102 hemoglobin day4 121 20APR2008
102 hemoglobin day7 128 23APR2008
;
run;
ods listing close;
ods rtf file='c:\temp\across.rtf';
proc report data=pt_data nowd nocompletecols;
title 'Using ACROSS Variables';
by patient;
column patient test result,day,date;
define patient / group;
define test /group ;
define day / across order=data ' ';
define date / across order=data f=date9. ' ';
define result / sum 'Results';
run;
ods rtf close;
[/pre]