**********************************************************************************; * *; * Title: redmon.sas *; * *; * Description: Performs reduced isotonic regression or reduced monotonic *; * regression in the case of one redictor variable and *; * a continuous outcome. Missing values are not allowed. *; * *; * Version: Version 1.0a, last modified April 27, 1997 and Sep 2, 1998 *; * *; * Written by: Sean O'Brien, Biostatistics, UNC Chapel Hill *; * *; * References: - Schell and Singh, "The Reduced Monotonic Regression Method", *; * JASA 92:128-135, 1997 *; * *; * - Robertson, Wright and Dykstra, Order-Restricted Statistical *; * Inference, New York, Wiley, 1988 *; * *; **********************************************************************************; **********************************************************************************; %MACRO REDMON( Data =_LAST_, /* NAME OF SAS DATASET */ X =, /* PREDICTOR VARIABLE(S) */ Y =, /* RESPONSE VARIABLE */ Z =, /* OPTIONAL BY-GROUP VARIABLE */ Freq =, /* OPTIONAL FREQ VAR */ Method =, /* SPECIFY DIRECTION OF TREND */ Alpha =, /* TARGET OVERALL TYPE I ERROR */ SLS =, /* BACKWARD ELIMINATION SELECTION LEVEL TO STAY */ Out =, /* REQUEST OUTPUT DATASETS */ Plot =, /* REQUEST HIGH-RESOLUTION PLOTS */ Cleanup =YES, /* REMOVE TEMPORARY DATASETS */ Tempchar =__, /* FIRST TWO CHARACTERS OF TEMPORARY DATASETS */ Nonotes =YES /* INVOKE SAS OPTION NONOTES TO PREVENT NOTES */ ); ************************************************************************************; %if (%upcase(&Nonotes) eq YES) %then %str(options nonotes;); ************************************************************************************; ************************************************************************************; %local error; %let error=0; %if %length(&X)=0 %then %do; %put E R R O R : Independent variable(s) must be specified.; %let error=1; %end; %if %length(&Y) = 0 %then %do; %put E R R O R : Dependent variable must be specified.; %let error=1; %end; %if (%scan(&y,2) ne) %then %do; %put E R R O R : Only one dependent variable allowed.; %let error=1; %end; %let i=1; %let temp=%scan(&Method,&i); %do %while (&temp ne); %if not %eval( (%upcase(&Temp) eq BEST) or (%upcase(&Temp) eq UP) or (%upcase(&Temp) eq DOWN)) %then %do; %put E R R O R: Invalid Method value (&Temp); %let error=1; %end; %let i=%eval(&i+1); %let temp=%scan(&Method,&i); %end; proc print data=&data(obs=0); var &x &y &z &freq;run; %if &syserr ne 0 %then %let error=1; %if &error=1 %then %goto stopit; %if ((&alpha ne) and (&sls ne)) %then %do; %put; %put W A R N I N G: ALPHA= and SLS= should not both be specified. ;; %put . . . . . . .: ALPHA= will be ignored.;; %end; %if (&alpha eq) %then %let alpha=.05; %if (&sls ne) %then %do; %put; %put N O T E: SLS= &sls has been requested by the user.; %put W A R N I N G: Use of the SLS= options does not control the overall alpha; %put . . . . . . error rate for H0: no trend vs. H1: isotonic trend.; %end; ************************************************************************************; ************************************************************************************; %local monosl isosl i ii test numzvars group j outputid Method data xbab ybab con; %let Binary=0; /* BINARY OPTION DEFUNCT */ %let Out =%eval(&Out ne); %let MONOSL= ; %let ISOSL=;; %let RESPONSE=%upcase(&Y); ************************************************************************************; ************************************************************************************; %let con=0; %if &data=_LAST_ %then %do;; proc contents data=&data out=&Tempchar.con noprint;; data _NULL_; set &Tempchar.con;; call symput('lib',libname);; call symput('mem',memname);; run;; %let con=1; %let data=%left(&lib).&mem; %end;; ************************************************************************************; ************************************************************************************; /*GET NAMES OF Z VARIABLES => "numzvars", "z1","z2","z3"... */ %let i=1; %local z&i; %let z&i=%scan(&z,&i); %let test=%eval(&&z&i ne); %do %while (&test); %let i=%eval(&i+1); %local z&i; %let z&i=%scan(&z,&i); %let test=%eval(&&z&i ne); %end; %let numzvars=%eval(&i-1); ************************************************************************************; ************************************************************************************; %if (&numzvars) %then %str(proc sort data=&data;by &z;); proc univariate data=&Data noprint; %if &freq ne %then %str(freq &freq;); %if (&numzvars) %then %str(by &z;); var &y; output out=&Tempchar&.WGTOBS nobs=_WGTOBS_ n=_N_ mean=_Mean_ sum=_sum_ css=css;run; ************************************************************************************; ************************************************************************************; data _NULL_; set &tempchar.WGTOBS nobs=groups; call symput("groups",left(trim(groups))); stop;run; ************************************************************************************; ************************************************************************************; data &tempchar.WGTOBS (rename=(N_=_N_)); set &tempchar.WGTOBS(rename=(_N_=N_)); drop logn logn2 lalpha lalpha2 inter inter2; groupid=_N_; call symput("n_grp"||left(_N_),left(trim(_WgtObs_))); /*CALCULATE SLS FOR REDUCED MONOTONIC REGRESSION*/ logn=log10(_wgtobs_);logn2=logn**2; lalpha=log10(&alpha);lalpha2=lalpha**2; inter=logn*lalpha; inter2=logn2*lalpha; monosl=10**(-.09061-.564*logn+.0536*logn2+1.238*lalpha+.0929*lalpha2+.1517*inter-.0331*inter2); call symput("MONOSL"||left(_N_), trim(monosl)); /*CALCULATE SLS FOR REDUCED ISOTONIC REGRESSION*/ lalpha=log10(&alpha*2);lalpha2=lalpha**2; inter=logn*lalpha; inter2=logn2*lalpha; isosl=10**(-.09061-.564*logn+.0536*logn2+1.238*lalpha+.0929*lalpha2+.1517*inter-.0331*inter2); call symput("ISOSL"||left(_N_), trim(isosl)); %do j=1 %to &numzvars; call symput("z&j.val"||left(_N_),trim(left(trim(&&z&j)))); %end; run; ************************************************************************************; ************************************************************************************; /*CREATE TITLE*/ %do group=1 %to &groups; %let title&group=; %do j=1 %to &numzvars; %local title&group; %let title&group=&&title&group &&z&j=&&z&j.val&group; %end; %end; data &Tempchar.DATA; %if (&numzvars) %then %str(merge &data &tempchar.WGTOBS; by &z;); %else %str(set &data ; if _N_=1 then set &tempchar.WGTOBS; retain _wgtobs_ _mean_ _sum_ css groupid;;); ; if &y ne . then output; run; ************************************************************************************; ************************************************************************************; %let OUTPUTID=0; %DO GROUP=1 %TO &GROUPS; data &Tempchar.wgtob2; point=&group; set &tempchar.WGTOBS point=point; output;stop; run; %let data=_data&group; %if (&numzvars) %then %str(title1 %quote(Controlling for) %quote(&&title&group););; %let i =1; %let XBAB=%scan(&x,&i); %let mthd=%scan(&Method,&i); %if &mthd= %then %let mthd=Best;; %do %while (&XBAB ne); %let outputid=%eval(&outputid+1); %doit( DATA = &Tempchar.DATA (where=(groupid=&group)), XVAR = &XBAB, YVAR = &Y, Freq = &freq, Method = &mthd, i = &i, nnn = &&n_grp&group, /* NEW */ SLS = &SLS, MONOSLS = &&MONOSL&group, ISOSLS = &&ISOSL&group, Out = &Out, OUTPUTID = &OutputID, TITLE = &&Title&Group, PLOT = &Plot); %let i = %eval(&i+1); %let XBAB=%scan(&x,&i); %let mthd=%scan(&Method,&i); %if &mthd= %then %let mthd=Best;; %end; %END; ************************************************************************************; ************************************************************************************; /*REMOVE TEMPORARY DATASETS*/ %if (%upcase(&Cleanup) eq YES) %then %do; proc datasets nolist library=work; delete &Tempchar.DATA &Tempchar.WGTOB2 &tempchar.FIT &tempchar.FSTATS &tempchar.LSTATS &tempchar.NUMSUM &tempchar.PARMS &tempchar.RESULT &tempchar.WGTOBS &tempchar.WORK %if %eval(%index(%upcase(&Method),BEST) or %index(%upcase(&Method),UP) or (&Method=)) %then %str( &tempchar.ISFIT1 &tempchar.PAVA1 &tempchar.SETUP1); %if %eval(%index(%upcase(&Method),BEST) or %index(%upcase(&Method),DOWN) or (&Method=)) %then %str( &tempchar.ISFIT0 &tempchar.PAVA0 &tempchar.SETUP0); %if %eval(&con=1) %then %str(&tempchar.con);; ;;;run;; %end; ************************************************************************************; options notes; %STOPIT:; %MEND REDMON; ************************************************************************************; %MACRO DOIT ( DATA =, XVAR =, YVAR =, Freq =, Method =, nnn =, i =, SLS =, MONOSLS =, ISOSLS =, Out =, OutputID =, Title =, Plot = ); ************************************************************************************; %let Up = %eval((%upcase(&Method)=UP ) OR (%upcase(&Method)=BEST)); %let Down = %eval((%upcase(&Method)=DOWN) OR (%upcase(&Method)=BEST)); %let Best = %eval(%upcase(&Method)=BEST); %put; %put * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; %put N O T E: EXPLANATORY VARIABLE=&XVAR METHOD=&method ; %put N O T E: &nnn observations used in regression; %if (&SLS eq) %then %do; %if %eval(&Best) %then %let SLS=&MONOSLS; %else %let SLS=&ISOSLS; %put N O T E: (ALPHA=&alpha N=&nnn METHOD=&method) ==> SLS=&sls; %if (&nnn gt 800) %then %put W A R N I N G: N=&nnn > 800 ==> Formula used to determine SLS may not be accurate.; %if (&nnn lt 20) %then %put W A R N I N G: N=&nnn < 20 ==> Formula used to determine SLS may not be accurate.; %if (&alpha gt .1) %then %put W A R N I N G: ALPHA=&alpha > .1 ==> Formula used to determine SLS may not be accurate.; %if (&alpha lt .01) %then %put W A R N I N G: ALPHA=&alpha < .01 ==> Formula used to determine SLS may not be accurate.; %end; %put * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; %put; ************************************************************************************; %if %eval(&Up) %then %do; proc sort data=&data out=&Tempchar.WORK(keep=&XVAR &YVAR &freq rename=(&XVAR=X &YVAR=Y)); by &XVAR descending &YVAR; run; data &tempchar.PAVA1 &tempchar.WORK(rename=(w=_wt_)); set &tempchar.WORK; %if &freq ne %then %str(w=&freq; drop &freq;); %else %str(w=1;); run; %pava(1, &tempchar.PAVA1); %end; %if %eval(&Down) %then %do; proc sort data=&data out=&Tempchar.WORK(keep=&XVAR &YVAR &freq rename=(&XVAR=X &YVAR=Y)); by &XVAR &YVAR; run; data &tempchar.PAVA0 &tempchar.WORK(rename=(w=_wt_)); set &tempchar.WORK; %if &freq ne %then %str(w=&freq; drop &freq;); %else %str(w=1;); run; %pava(0, &tempchar.PAVA0); %end; ************************************************************************************; ************************************************************************************; %if %eval(&Up) %then %SetUp(1); %if %eval(&Down) %then %SetUp(0); %if %eval(&Best) %then %do; data _NULL_; set &tempchar.ISFIT1(rename=(isosse=isosseup)); set &tempchar.ISFIT0(rename=(isosse=isossedo)); up=isosseup lt isossedo; down=1-up; call symput("Up",left(up)); call symput("Down",left(Down)); run; %end; %reduce(&UP,&SLS); %results(&XVAR,&YVAR,&Up,&Plot); ************************************************************************************; ************************************************************************************; /* OUTPUT DATASETS */ %if (%eval(&Out) and(%upcase(&Out) ne NO))%then %do; proc datasets nolist library=work ; delete _FIT&OutputID _FINAL&OutputID; modify &tempchar.FIT (label="Y=&YVAR, X=&XVAR BYGROUP=&TITLE"); rename y=&yvar x=&xvar %if (&freq ne) %then %str(_wt_=&freq;);; modify &tempchar.RESULT(label="Y=&YVAR, X=&XVAR BYGROUP=&TITLE"); change &tempchar.FIT = _FIT&OutputID &tempchar.RESULT=_FINAL&OutputID; run; %end; ************************************************************************************; %MEND DOIT; ************************************************************************************; ************************************************************************************; %MACRO PAVA(up,file); ************************************************************************************; %local compare; %let compare = gt; %if &up = 0 %then %let compare = lt; data _NULL_; set &file NOBS=N;;; call symput('NumObs',left(N)); run; data &File (keep=pavafit xxmin xxmax ww nn llevel sum cumn cumw rename=(xxmin =xmin xxmax =xmax ww =w nn =n llevel=level)); array _w (*) w1-w&NumObs ; array _n (*) n1-n&NumObs ; array xmin (*) xmin1-xmin&NumObs; array xmax (*) xmax1-xmax&NumObs; array ymean (*) mean1-mean&NumObs; do i = 1 to &NumObs; set &file; _w[i] = w; _n[i] = 1; ymean[i]=y; xmin[i]=x; xmax[i]=x; end; NUMSETS = &NUMOBS; REV=1; do while (REV); REV =0; _mean =ymean[1]; _wt =_w[1]; _num =_n[1]; _sum =_mean*_wt; _xmin =xmin[1]; _xmax =xmax[1]; _level = 1; do i = 2 to NUMSETS; if ymean[i] &compare _mean then do; /* IF IN ORDER */ ymean[_Level]=_mean; _w[_Level] =_wt; _n[_Level] =_num; xmin[_Level] = _xmin; xmax[_level] = _xmax; _mean = ymean[i]; _wt = _w[i]; _num = _n[i]; _xmin = xmin[i]; _xmax = xmax[i]; _sum = _mean*_wt; _level= _level+1; end; else do; _sum = _sum + ymean[i]*_w[i]; _wt = _wt + _w[i]; _num = _num + _n[i]; _mean = _sum/_wt; _xmax= xmax[i]; REV=REV+1; end; end; ymean[_Level]=_mean; _w[_Level] =_wt; _n[_Level] =_Num; xmin[_Level] = _xmin; xmax[_level] = _xmax; NUMSETS = _Level; end; cumn = 0; do i = 1 to _LEVEL; pavafit=ymean[i]; xxmin =xmin[i]; xxmax =xmax[i]; ww=_w[i]; nn=_n[i]; sum =ymean[i]*ww; cumn+nn; cumw+ww; llevel=i; output; end; run; ************************************************************************************; %MEND PAVA; ************************************************************************************; ************************************************************************************; %MACRO SETUP(Up); ************************************************************************************; data _NULL_; if _N_=1 then set &tempchar.PAVA&UP nobs=sets;;; call symput("NumSets",left(sets)); run; data &tempchar.SETUP&UP(drop=ISOSSE) &tempchar.ISFIT&Up(keep=ISOSSE); retain ISOSSE 0; set &tempchar.PAVA&UP end=eof; do index1 = 1 to N; set &tempchar.WORK; %do ii = 2 %to &NumSets; Var&ii =0; if &ii le _n_ then Var&ii= 1; %end; ISOSSE=ISOSSE+_wt_*(y-pavafit)**2; freq=_wt_; output &tempchar.SetUp&Up; end; if eof then output &tempchar.ISFIT&Up; run; %mend; ************************************************************************************; ************************************************************************************; %MACRO REDUCE(Up, Alpha); ************************************************************************************; /*GET NUMBER OF LEVEL SETS, NUMBER OF OBSERVATIONS*/ data _NULL_; if _N_=1 then do; set &tempchar.PAVA&UP nobs=sets; set &tempchar.SETUP&UP nobs=NumObs; call symput("NumSets",left(sets)); call symput("NumObs",left(NumObs)); end; run; %if %eval(&NumSets gt 1) %then %let myvars=var2-var&NumSets; %else %let myvars=; proc reg data=&Tempchar.SETUP&UP noprint outest=&Tempchar.PARMS( rename=(intercep=var1 _P_=REDQ _EDF_=REDEDF _RSQ_=REDRSQ _SSE_=REDSSE)); model y= &myvars/selection=backward sls=&Alpha sse; freq freq; output out=&Tempchar.FIT( keep= x y pavafit redfit _wt_ residual cookd) predicted=redfit residual=residual cookd=cookd; run; quit; ************************************************************************************; %MEND REDUCE; ************************************************************************************; ************************************************************************************; %MACRO RESULTS(XVAR,YVAR,Up,Plot); ************************************************************************************; options ls=100; data _NULL_; if _N_=1 then set &tempchar.PAVA&UP nobs=sets; call symput("NumSets",left(sets)); run; ************************************************************************************; /* ----------------Combine level sets ------------ */ data &tempchar.RESULT (keep=xmin xmax estimate redfit w sum /*n*/ level /*cumn*/ cumw) &tempchar.NUMSUM (keep=level n1-n&NumSets w1-w&NumSets sum1-sum&NumSets cumw level); array xn (*) n1-n&NumSets; array xw (*) w1-w&NumSets; array xsum (*) sum1-sum&NumSets; array vars (*) var1-var&NumSets; retain xmin xmax redfit; retain n1-n&NumSets w1-w&NumSets sum1-sum&NumSets; set &tempchar.PAVA&UP (keep = xmin xmax pavafit w sum n level cumn cumw rename=(xmin=fmin xmax=lmax pavafit=gg w=ww sum=csum n=nn level=llevel /*cumn=ccumn cumw=ccumw*/)) end=eof; if _N_=1 then set &tempchar.PARMS; IF vars[_N_] gt . then DO; IF _N_ gt 1 then do; output &tempchar.RESULT; xn[level]=n; xsum[level]=sum; xw[level]=w; end; level+1; xmin=fmin; n=0;w=0;sum=0; estimate+VARS[_N_]; END; n+nn; w+ww; sum+csum;redfit=sum/w; xmax=lmax; if eof then do; output &tempchar.RESULT; xn[level]=n; xsum[level]=sum; xw[level]=w; output &tempchar.NUMSUM; end; run; ************************************************************************************; ************************************************************************************; * -------------- Calculate added-last tests for each parameter ------------------ *; data &tempchar.FSTATS (keep=f p level stdev) ; array fnumerat(*) fnumer1-fnumer&NumSets; array xn(*) n1-n&NumSets; array xw(*) w1-w&NumSets; array xsum(*) sum1-sum&NumSets; array mse(*) mse1-mse&NumSets; retain w1-w&NumSets sum1-sum&NumSets; set &tempchar.NUMSUM (rename=(level=llevel cumw=wtotal)); A=.;B=.; C=.; DO I = 1 to LLEVEL ; amean=xsum[i]/xw[i]; if i gt 1 then bmean=(xsum[i-1]+xsum[i])/(xw[i-1]+xw[i]); else bmean=.; if i+1 le llevel then cmean=(xsum[i]+xsum[i+1])/(xw[i]+xw[i+1]); else cmean=.; Aprime=A; Bprime=B; Cprime=C; A=0; B=0; C=0; do j= 1 to xn[i]; index+1; set &tempchar.FIT point=index; A+_WT_*(y-amean)**2; B+_WT_*(y-bmean)**2; C+_WT_*(y-cmean)**2; end; SSER=Cprime+B; SSEF=Aprime+A; SSEFULL+A; fnumerat[i]=SSER-SSEF; mse[i]=A/(xw[i]-1); END; do i=1 to llevel; f=fnumerat[i]/(SSEFULL/(wtotal-llevel)); P=1-probf(F,1,wtotal-llevel); stdev=sqrt(mse[i]); level=i; output; end; stop; run; ************************************************************************************; /*MERGE &tempchar.FSTATS ONTO RESULTS*/ data &tempchar.RESULT; merge &tempchar.RESULT &tempchar.FSTATS; by level;run; ************************************************************************************; *--------GET LINEAR REGRESSION SSE and RSQUARE-------*; proc reg data=&tempchar.WORK noprint outest=&Tempchar.LSTATS( keep = _RSQ_ _SSE_ _P_ _EDF_ rename=(_RSQ_=LINRSQ _SSE_=LINSSE _P_=LINQ _EDF_=LINEDF)) ; model y=x/sse; freq _WT_; run; ************************************************************************************; ************************************************************************************; *-----PRINT SUMMARY OF RESULTS----*; data _NULL_; file print; if _N_=1 then do; set &tempchar.PAVA&UP nobs=n_pava; set &tempchar.RESULT nobs=n_parse; set &tempchar.ISFIT&UP; set &tempchar.FSTATS; set &tempchar.LSTATS; set &tempchar.WGTOB2(keep=css); set &tempchar.PARMS(keep=REDRSQ REDSSE REDQ REDEDF); ISORSQ=1-ISOSSE/CSS; LINF=(LINEDF*LINRSQ)/(1-LINRSQ); LINP=1-probf(LINF,1,LINEDF); IF REDQ GT 1 THEN DO; REDF =(REDEDF*REDRSQ)/((1-REDRSQ)*(REDQ-1)); REDP=1-probf(REDF,REDQ-1,REDEDF); END; ELSE DO; REDF=.; REDP=.;END; put /// @1 "Independent Variable: &XVAR"; put @1 "Response Variable: &YVAR" @38 %if %eval(&up) %then %str("INCREASING TREND";); %else %str("DECREASING TREND";); /*SUMMARY TABLE*/ put //@24 " SSE " @38 "LEVEL SETS" @56 " RSQUARE" @70 "PVAL*"; put @1 "ISOTONIC REG " @24 ISOSSE best7. @38 n_pava @54 ISORSQ 7.4-r @70 "." ; put @1 "REDUCED ISO REG" @24 REDSSE best7. @38 n_parse @54 REDRSQ 7.4-r @70 REDP 7.5; put @1 "LINEAR REGRESSION" @24 LINSSE best7. @38 " . " @54 LINRSQ 7.4-r @70 LINP 7.5; put @1 "INTERCEPT ONLY " @24 CSS best7. @38 " . " @54 " . " @70 "." ; put //// @29"***ISOTONIC REGRESSION FIT***"/; put @1 " LEVEL" @10 " XMIN " @25 " XMAX " @40 " ESTIMATE " @55 " W "; put @1 "______" @10 "__________" @25 "__________" @40 "__________" @55 "_____"; end; do k=1 to n_pava; set &tempchar.PAVA&UP; put @1 level 4.0 @10 xmin best10. @25 xmax best10. @40 pavafit best10. @55 w best5.-c; end; put //// @19 "***REDUCED MONOTONIC REGRESSION FIT***"/; put @1 " LEVEL" @10 " XMIN " @25 " XMAX " @40 " ESTIMATE " @55 "STDEV" @65 " W " @75 " F" @85 "PVAL*"; put @1 "________" @10 "__________" @25 "__________" @40 "__________" @55 "_____" @65 "_____" @75 "______" @85 "______"; do k=1 to n_parse; set &tempchar.RESULT; put @1 level 3.0 @10 xmin best10. @25 xmax best10. @40 redfit best10. @55 stdev best7. @65 w best5.-c @75 f 6.2 @85 p 7.5; end; put // @3 "* Pvalues are unadjusted"; stop; run; ************************************************************************************; ************************************************************************************; * --------------- PLOTS ----------------------------*; %if ((&plot ne) and (%upcase(&plot) ne NO)) %then %do; %let gdevice=&sysdevic; data _NULL_; set &tempchar.RESULT end=eof nobs=__n; call symput("numobs",left(trim(__n))); if not eof then call symput("HREF"||left(_N_),trim(left(trim(xmax)))); run; %let href=; %do i=1 %to %eval(&numobs-1); %let href=&href &&href&i; %end; goptions reset=(axis, legend, pattern, symbol, footnote) hpos=0 vpos=0 htext= ftext= ctext= target= gaccess= gsfmode=; goptions ctext=blue graphrc interpol=join rotate=landscape; GOPTIONS GUNIT=PCT HTEXT=2 FTEXT=SWISSB CTEXT=BLACK; %if (%upcase(%scan(&plot,1))=FILE) %then %str(GOPTIONS GACCESS=GSASFILE DEVICE=PS LFACTOR=5;); symbol2 c=DEFAULT i=STEPSLJ v=NONE; symbol1 c=DEFAULT i=NONE v=DOT cv=BLACK h=.1 CM; axis1 color=blue width=2.0; axis2 color=blue width=2.0; axis3 color=blue width=2.0; %let dir=%scan(&plot,2); proc gplot data=&tempchar.FIT; %if (%upcase(%scan(&plot,1))=FILE) %then %str(FILENAME GSASFILE "&dir._PLOT&OutputID..PS";);; title2 "Reduced Monotonic Regression"; plot (Y redfit) * X / overlay haxis=axis1 vaxis=axis2; plot (RESIDUAL ) * X / overlay haxis=axis1 vaxis=axis2 vref=0 %if (&href ne) %then href=(&href);; label x="&XVAR" y="&YVAR" redfit="&YVAR"; run;quit; goptions device=&gdevice; %end; ************************************************************************************; %MEND RESULTS; ************************************************************************************;