Hi all, Sorry for the delayed response, still waiting on the script the campus statisticians are building - will provide when I receive it. In the meantime, here's the code based almost entirely off of the directions Reeza provided (thank you, Reeza!) along with some sample data at the end to show that their iteration works. When working with the entire dataset, I have to restart SAS before switching between the three options to calculate AUC, otherwise baseline will not be calculated correctly - it will apply the first subject and period to all subjects and periods. I tried deleting the SQL table before switching between options and that doesn't appear to resolve the issue. Insignificant inconvenience for what is gained by the program. %MACRO AUC(dataset, baseline, subject, treatment, output);
proc sql noprint;
select mean(yValue) format=6.2 into :baseY
from &dataset
where subject="&subject." and treatment="&treatment." and Xtime <= 0;
quit;
DATA &output;
SET &dataset;
where subject="&subject." and treatment="&treatment." and Xtime GE 0;
RETAIN Basevalue;
IF &baseline = 0 THEN Basevalue = 0.0;
* &BaseY shown in the following statement is the macro variable defined in any one of the above SQL
procedures;
IF (&baseline = 1 OR &baseline = 2) AND _N_ = 1 THEN Basevalue =
&BaseY;
if Xtime=0 then Yvalue = &BaseY;
Yvalue = Yvalue - Basevalue;
DROP LagTime LagValue;
LagTime = LAG(Xtime);
LagValue = LAG(Yvalue);
IF Xtime = 0 THEN DO;
LagTime = 0;
LagValue = 0;
END;
IF &baseline = 2 AND Yvalue > 0 AND LagValue <= 0.0 THEN DO;
* Connecting line with positive slope, only the area of right triangle (above baseline) is counted.;
DROP Ratio;
Ratio = Yvalue / (ABS(LagValue)+Yvalue);
Trapezoid = Ratio*(Xtime-LagTime)*(Yvalue+0.00)/2;
END;
ELSE IF &baseline = 2 AND Yvalue < 0 AND LagValue >= 0.0 THEN DO;
* Connecting line with negative slope, only the area of left triangle (above baseline) is counted.;
DROP Ratio;
Ratio = LagValue / (LagValue+ABS(Yvalue));
Trapezoid = Ratio*(Xtime-LagTime)*(0.00+LagValue)/2;
END;
ELSE IF &baseline = 2 AND Yvalue < 0 AND LagValue < 0 THEN Trapezoid =
0.0;
* Negative trapezoidal area is not counted.;
ELSE Trapezoid = (Xtime-LagTime)*(Yvalue+LagValue)/2;
* The rest of all positive trapezoidal areas are counted.;
SumTrapezoid + Trapezoid;
FORMAT Trapezoid SumTrapezoid 8.3;
RUN;
%MEND AUC;
PROC SQL;
create table macro_call as
SELECT distinct 2 as baseline, subject, treatment
from gluc2;
QUIT;
*execute the macro for each line; data demo; set macro_call; str =
catt('%AUC(dataset=gluc2', ', baseline=', baseline, ', subject = ', subject, ', treatment =
', treatment, ', output= OUT_', catx('_', subject, treatment), ');'); call execute(str); run;
data combined_out_baseline2;
set out_: ;
run;
proc sort data = combined_out_baseline2;
by subject period;
run;
proc print data = combined_out_baseline2;
run;
/*code below is for if you just want to try running the macro on one subject and period instead of the whole dataset*/
/*(dataset, baseline, subject, treatment, output)*/
%AUC(gluc2,1,5919,CX, practice);
proc print data = practice;
run;
/*heres the whole dataset*/
data gluc;
input Subject $ period $ xtime yvalue;
datalines;
5901 1 -15 110.5
5901 1 0 113.6
5901 1 30 205
5901 1 60 240
5901 1 90 230
5901 1 120 195
5901 1 150 125
5901 1 180 105.2
5901 2 -15 110.1
5901 2 0 110.6
5901 2 30 201.1
5901 2 60 270.5
5901 2 90 220.6
5901 2 120 205.4
5901 2 150 180.7
5901 2 180 130.6
5901 3 -15 115.2
5901 3 0 115.9
5901 3 30 188.8
5901 3 60 260.5
5901 3 90 250.6
5901 3 120 180.4
5901 3 150 145.7
5901 3 180 115.0
;
run;
/* Add treatment variable to glucose dataset based on period info */
data gluc2;
set gluc;
length treatment $8;
if subject = '5901' and period = '1' then treatment = 'CX';
if subject = '5901' and period = '2' then treatment = 'BY';
if subject = '5901' and period = '3' then treatment = 'AZ';
run;
... View more