*
; options nosource; /* QUICKINT - CALCULATES INTEGRATED FUNCTION FROM A FUNCTION GIVEN IN PARAMETERFORM; AREA TO X-AXIS or BETWEEN TWO FUNCTIONS; AREA UNDER A ROC-CURVE. Written: October 24,25, 1994, enhanced : December 12,1994 January 20,1995 April 21,1995 August 21,1998 Developed using SAS 6.08 for Windows Runable: SAS 6.09 under AIX Unix; SAS 6.10 - 6.12 for Windows Author: Arnold Schick Procs: PROC DATASETS and PROC SORT Other: SAS MACRO language Macros: only QUICKINT Note: Do not use _TEMP_ as a data set name. Please don't call %QUICKINT; or %QUICKINT(); Macro Call: %QUICKINT(DATA,RESULT,X,Y,C,SORT); MACRO VARIABLE DESCRIPTION ------------------+------------------------------------------------- In Request: DATA Name of SAS data set with input data. If this parameter is missing or blank _LAST_ is used. Integration-interval is between minimum and maximum value of independent variable. No more values shold be in input data set (if necessary select data at first). RESULT Name of SAS data set created by this macro. If missing or blank stops the %macro. 2 new variables are created: FACE and Y_SOURCE . X Variablename of independent variable in input SAS data set DATA. If missing or blank, X is used. Y Variablename of dependent variable in input SAS data set DATA. If missing or blank, Y is used. C Value of integration-constant. If missing or blank, zero is used. SORT Name of option for controlling of sorting the input dataset by the independent variable. If name of options other than SORT, blank or missing, no sorting is applied. Useful for calculating of area between two functions (see example at the end). Example: data one; do x=-1 to 8*atan(1) by atan(1)/64; y=cos(x); output; end; run; *%macro quickint (data,result, x, y, c,sort); %quickint (one ,two); %quickint (one ,two , x, y,-1,sort); For more information: Arnold Schick E-Mail: schick@yours.com If you find an error-condition (it is provided 'as it is') please let me know about this error-condition. And when you have good tips for better formulation in SAS, let it also know. */ %macro quickint (data,result,x,y,c,sort); options nosource nostimer nosymbolgen nonotes nomprint; %if &data = or &data = . %then %let data = _LAST_ ; %if &result = or &result = . %then %goto quit_1; %if &x = or &x = . %then %let x = x; %if &y = or &y = . %then %let y = y; %if &sort = or &sort = . or %upcase(&sort) = %upcase(sort) %then %let sort = sort; %else %let sort = notsort; data _NULL_; cc = symget('c')/1.0 ; if cc = . then cc = 0 ; call symput('c',cc); run; %local empty; data _NULL_ ; if 0 then set &data nobs=last; call symput('empty',last); stop; run; %if &empty < 2 %then %goto quit_2; %if %upcase(&sort) ^= %STR(SORT) %then %do; data _temp_; set &data; run; %goto next; %end; proc sort data=&data out=_temp_; by &x; run; %next : ; data &result; set _temp_ nobs=n end=last; length face y_source y_sourc2 Ax Ay 8 ; keep &x &y y_source face mx my; x_previo = lag(&x); y_previo = lag(&y); xm = (&x-x_previo)/2 + x_previo; retain x_begin ; if _N_ = 1 then do; y_sourc2 = &c; y_source = 0; face = 0; x_begin = &x; Ax = 0; Ay = 0; Mx = &x; My = &y/2; end; else do; y_sourc2 = (xm-x_previo)*y_previo + (&x-xm)*&y; face + abs(y_sourc2); if (&y + y_previo)=0 then x0=xm; else x0=(&x-(&x-x_previo)/3*(&y+2*y_previo)/(&y+y_previo)); Ax + abs(y_sourc2)*x0; if (&x-x_previo)=0 then mm=0; else mm=(&y-y_previo)/2/(&x-x_previo); bb = &y/2-mm*&x; Ay + abs(y_sourc2)*(mm*x0+bb); Mx = Ax/face; My = Ay/face; end; y_source + y_sourc2 ; if last then do; file print; x_end = &x ; c=&c; if face ^=0 then do; Ax = Ax/face; Ay = Ay/face; end; else do; Ax=.; Ay=.; end; face=abs(face); put ' Results of QUICK-Integration'; put ' '; put ' area=' face ' with main point at: ' "&x" '=' Ax ' , ' "&y" '=' Ay; put ' integrated between ' x_begin ' and ' x_end ; put ' with ' n ' points (observations from input data set ' "&data" ' were ' "&sort" 'ed)' ; put ' integration constant=' c '.' ; put ' Results are stored into data set ' "&result" ; end; run; proc datasets nolist; delete _temp_ ; quit; %goto final ; %quit_1 : %put MACRO-HALT: Please define result data set. ; %goto final; %quit_2 : %put MACRO-HALT: Number of observations in input data set less than 2 or; %put input data set &data is empty. ; %final : ; options source stimer notes; %mend quickint; options source; /*Example section */ *integration of a function; data one; *creates function values and stores into dataset ONE; do x=0 to 4*atan(1) by atan(1)/128; y=sin(x); output; end; run; *%macro quickint (data,result,x,y, c,sort); %quickint (one ,result, , ,-1); *exact value for area assumes 2.0; proc gplot; *displays the results; symbol i=join r=123 c=; plot (y y_source face) * x / overlay; run; quit; *special example: area between two functions; data one; *the first function must be sorted in ascending order; do x=-1 to 4 by atan(1)/128; y=sin(x*x*0.89)-0.3; output; end; run; data two; *the second function must be sorted in descending order; do x=4 to -1 by -atan(1)/128; y=-sin(x); output; end; x=-1; y=sin(x*x*0.89)-0.3; output; *last value-pair should be the first values from ONE; run; proc append base=one data=two; run; *both functions are included in dataset ONE; %quickint(one,result,x,y,0,notsort); *needs macro-option NOTSORT, integration-constant is set to 0 !; *dispays area between both functions; axis1 order=-1 to 4 by 1 length=11 cm; axis2 order=-2 to 2 by 1 length=11 cm; symbol i=join; proc gplot; plot y *x/areas=1 haxis=axis1 vaxis=axis2; run; quit; *example: calculating of an ara from a circle with radius=1, exact area=3.141592...; data two; do alpha=0 to 4*atan(1) by atan(1)/64; x=cos(alpha); y=sin(alpha); output; end; run; proc sort data=two; by x; run; proc sort data=two out=three; by descending x; run; data three; set three; y=-y; run; proc append base=two data=three; run; %quickint(two,result,x,y,0,notsort); *needs macro-option NOTSORT and integration-constant is set to 0; axis1 order=-1 to 1 by 1 length=8 cm; axis2 order=-1 to 1 by 1 length=8 cm; symbol i=join; proc gplot; plot y *x/areas=1 haxis=axis1 vaxis=axis2; run; quit; /* End of example section */ *;