*
; options nosource; /* NEAREST - CALCULATES MIN, MAX, MEAN DISTANCES OF FUNCTION-VALUES WHERE THE DISTANCES CAN BE SQUARE OR ROOT OF SQUARE. Written: June 20, 1995 Updated: January 17, 1996 Developed using SAS 6.10 for Windows Run able: SAS 6.09 under AIX Unix, SAS 6.08 for Windows, SAS 6.04 under DOS Author: Arnold Schick Procs: PROC RANK, SORT and DATASETS Other: SAS MACRO language Macros: only NEAREST Note: Do not use _TEMP_ as a data set name. Please don't call %NEAREST; or %NEAREST(); Macro Call: %NEAREST(DATA,N,RESULT,X,Y,SQRT); MACRO VARIABLE DESCRIPTION ------------------+------------------------------------------------- In Request: DATA Name of SAS data set with input data. If this parameter is missing or blank _LAST_ is used. N Number of nearest function-values. If blank or missing N is set to 5. RESULT Name of SAS data set created by this macro. If missing or blank stops the %macro. Two new variables are created: D and RANK_D. D obtains the calculated distance or square distance RANK_D abtains the rank of D. 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. SQRT Name of option for sort of distance. SQRT means the direct-distance to the previous function-values, calculated as: d = sqrt(Xi-Xi-1)**2 + (Yi-Yi-1)) if otherwise specified, square-distance: d = (Xi-Xi-1)**2 + (Yi-Yi-1)**2 is used. Example: data one; do x=-1 to 8*atan(1) by atan(1)/64; y=sin(x); output; end; run; *%macro nearest (data,n,result, x, y, sqrt); %nearest ( one,6,two, x, y, nosqrt ); %nearest ( one,5,two); For more information: Arnold Schick University of Marburg Academic Computing Center Hans-Meerwein-Str. 35032 Marburg/Lahn Germany Internet: schick@hrz.uni-marburg.de 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. */ options nosource; %macro nearest(data,n,result,x,y,sqrt); options nosource nostimer nosymbolgen nonotes nomprint; %if &data = or &data = . %then %let data = _LAST_ ; %if &n = or &n = . %then %let n = 5; %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 &sqrt = or &sqrt = . or %upcase(&sqrt) = %upcase(sqrt) %then %let sqrt = sqrt; %else %let sqrt = square; %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(&sqrt) = %STR(SQRT) %then %do; data _temp_; set &data; d=sqrt(dif(&x)**2 + dif(&y)**2); n=_N_; if n=1 then delete; run; %end; %else %do; data _temp_; set &data; d=dif(&x)**2 + dif(&y)**2; n=_N_; if n=1 then delete; run; %end; proc rank data=_temp_ out=&result; var d; ranks rank_d; run; proc sort data=&result out=&result; by rank_d; run; options notes; data &result; set &result nobs=obs; if _N_ < &n+1 or _N_ > obs-&n; run; options nonotes; 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 nearest; options source; /* *Example; *creates simple function into dataset ONE; data one; do x=-1 to 1 by 0.01; y= cos(x/cos(x)); output; end; run; *%macro nearest (data,n,result,x,y,sqrt); %nearest (one ,2,result, , ,sqrt); proc print data=result; *prints the result; run; quit; %nearest (one ,9999,result, , ,sqrt); proc gplot data=result; *displays the results; symbol i=join r=123 ; plot (y d) * x / nolegend; run; quit; */ *;