*
; options nosource; /* DIFFER - CALCULATES THE DERIVATIVE FUNCTION FROM A FUNCTION GIVEN IN PARAMETERFORM Written: October 31, 1994 Developed using SAS 6.08 for Windows Run able: SAS 6.09 under AIX Unix Author: Arnold Schick Procs: PROC MEANS, PROC DATASETS and PROC SORT Other: SAS MACRO language Macros: only DIFFER Note: Do not use _TEMP_ or _MINMAX_ as a data set name. Help informations are given out by calling of %DIFFER; or %DIFFER(help); or %DIFFER(?); The first two and last two derivative function-values are approximated. Macro Call: %DIFFER(DATA,RESULT,X,Y,M); MACRO VARIABLE DESCRIPTION ------------------+------------------------------------------------- In Request: DATA Name of SAS data set with input data. If this parameter is missing _LAST_ is used, on blank parameter stops the macro. RESULT Name of SAS data set created by this macro. If missing or blank _NEW_ is used. One new variable is created: Y_D. Y_D is the variable with the values of the derivative function. X Variblename 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. M Value of slope-factor for correction of a slope in input-funtion. If M is zero, blank or missing, a slope correction is not done. Example: data one; do x=0 to 8*atan(1) by atan(1)/4; y=sin(x); output; end; run; *%macro differ (data,result, x, y, m); %differ (one ,two); %differ (one ,two , x, y,-0.001); Reference: none 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 with SAS, let it also know. */ %macro differ (data,result,x,y,m); options nosource nostimer nonotes nosymbolgen; %if &data = and &result = and &x = and &y = or %upcase(&data) = HELP or &data = ? %then %do; %put This macro computes the first derivation of a parameter-function. It needs; %put N defined points: if necessary, the data are to spline or smooth at first.; %put It should called by: DIFFER( input-data, result, indep-var, dep-var, slope ); %put where:; %put input-data : datasetname with data for derivation, if missing, _LAST_ is used; %put result : datasetname of result, if not, _NEW_ is used. Variable Y_D will be created; %put indep-var : variablename of independent variable in input-data set, default is X; %put dep-var : variablename of dependent variable in input-data set, default is Y; %put slope : value of slope-factor to modify input-data, if not, zero is used.; %put Missings or blanks are allowed on parameters.; %goto fin; %end; %if &data = . %then %do; %let data = _LAST_ ; %put macro-info: input data set is _LAST_; %end; %if &data = %then %goto quit_1; %if &result = or &result = . %then %do; %let result = _NEW_; %put macro-info: output data set is _NEW_; %end; %if &x = or &x = . %then %do; %let x = x; %put macro-info: independent variable is X; %end; %if &y = or &y = . %then %do; %let y = y; %put macro-info: dependent variable is Y; %end; data _NULL_; b = symget ('m') / 1; if b = . then b = 0; call symput('m',b); 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; proc means data=&data noprint; var &x; output out=_MINMAX_ min=min max=max n=n; run; data _NULL_; set _MINMAX_; p = round((max-min)/0.01 + 0.5,1); if p > n then put 'macro-halt: Please spline/smooth data at first with minimum of ' p ' points, available are n=' n; call symput('p',p); call symput('n',n); run; %if &p > &n %then %goto fin; proc sort data=&data out=_TEMP_; by &x; run; data _NULL_; set _TEMP_ (where=(&x is not missing or &y is not missing)); length dy dy_1 dy_2 8 ; x_previo = Lag(&x); y_previo = Lag(&y) + lag(&x)*&m; if _N_ > 1 then do; if m ^= 0 then dy = -(y_previo - &y + &x*&m) / (&x - x_previo); else dy = -(y_previo - &y ) / (&x - x_previo); dy_2 = (lag(dy) + dy)/2; dy_1 = lag(dy) -(dy_2 - lag(dy)); if _N_ = 3 then do; call symput('dy_2',dy_2); call symput('dy_1',dy_1); stop; end; end; run; data &result (rename=(x_previo=&x y_previo=&y) keep = x_previo y_previo y_d); set _TEMP_ (where=(&x is not missing or &y is not missing)) end=last; length y_diff y_d 8 ; x_previo = lag(&x); y_previo = lag(&y) + x_previo*&m; if _N_ = 2 then do; y_d=&dy_1; output; end; if _N_ > 2 then do; if &m ^= 0 then y_diff = -(y_previo - &y + &x*&m) /(&x - x_previo); else y_diff = -(y_previo - &y) /(&x - x_previo); y_d = (lag(y_diff) + y_diff)/2; if _N_ = 3 then y_d=&dy_2; k=lag(y_d); output; end; if last then do; x_previo = &x; y_previo = &y; y_d = y_d - (k - y_d); output; end; run; proc datasets nolist; delete _MINMAX_ _TEMP_; quit; %goto fin; %quit_1 : %put macro-halt: Please define input-data set; %goto fin; %quit_2 : %put macro-halt: Input data set &data is empty or has less than 2 points; %fin : ; options source stimer notes; %mend differ; options source; *Example:; data one; do x=-2 to 6.29 by atan(1)/128; y=cos(x); output; end; run; %differ(one,two); proc gplot; plot (y y_d) * x /overlay; run; %differ; *;