%macro default_knots(librefknots=,data=,varknots=, numknots=); proc sort data=&data (keep=&varknots) out=q1; by &varknots; run; data q2; set q1; by &varknots; if first.&varknots; run; data &librefknots..knots; set q2 nobs=n; knotsp=int(n/5); if knotsp>=35 then kmx=35; else if knotsp<35 then kmx=knotsp; %if &numknots ne %then %do; ktemp=&numknots; if 1 <= ktemp <= 35 then kmx=ktemp; %end; kintrvl=int(n/kmx); knotsok=mod(_n_,kintrvl); knots=&varknots; if knotsok=0 then output; keep knots; run; %mend; %macro scatter_smooth(libref=,data=,x=,y=,knotdata=, knots=); data dataw; set &data (keep=&y &x); m=1; run; data kt1; set &knotdata nobs=nk; call symput('nkt',nk); run; proc transpose data=&knotdata prefix=knots out=knotst; var &knots; run; data &libref..knotst; set knotst; m=1; run; data dataw; merge dataw &libref..knotst; by m; %let nk=&nkt; array Z (&nk) Z1-Z&nk; array knots (&nk) knots1-knots&nk; do k=1 to &nk; Z(k)=&x-knots(k); if Z(k) < 0 then Z(k)=0; end; drop knots1-knots&nk _name_; run; ods output CovParms=&libref..varcomp; proc mixed; model &y = &x / solution outp=&libref..yhat; random Z1-Z&nk / type=toep(1) s; run; %mend;