I have to manually create basis functions for a variable but SAS doesn't seem to have a procedure to do it. I am using Frank Harrell's macro RCSPLINE but the basis variables are not identical to those created by SAS. It seems like SAS is dividing the second basis by 4 and the last one by 4.5. Not sure where these numbers come from for the example given below.
data simulation;
do i=1 to 10000;
t=rand('uniform',0,10);
p=1/(1+exp(sin(t)));
y=rand('bernoulli',p);
output;
end;
run;
*model a natural cubic spline;
*and store the result in "mystore";
proc logistic data=simulation OUTDESIGN=splines;
effect myspline=spline(t/knotmethod=list(1,2,3,4) NATURALCUBIC);
model y(event="1")=myspline;
store mystore;
run;
/*-------------------------
MACRO FOR CUBIC SPLINES
-------------------------*/
%macro rcspline(x,knot1,knot2,knot3,knot4,knot5,knot6,knot7,knot8,knot9,knot10, norm=2);
%LOCAL j v7 k tk tk1 t k1 k2;
%LET v7=&x; %IF %length(&v7)=8 %THEN %LET v7=%SUBSTR(&v7,1,7);
%*get no. knots, last knot, next to last knot;
%DO k=1 %TO 10;
%IF %QUOTE(&&knot&k)= %THEN %GOTO nomorek;
%END;
%LET k=11;
%nomorek: %LET k=%EVAL(&k-1); %LET k1=%EVAL(&k-1); %LET k2=%EVAL(&k-2);
%IF &k<3 %THEN %PUT ERROR: ❤️ knots given. no spline variables CREATEd.;
%ELSE %DO;
%LET tk=&&knot&k;
%LET tk1=&&knot&k1;
DROP _kd_; _kd_=
%IF &norm=0 %THEN 1;
%ELSE %IF &norm=1 %THEN &tk - &tk1;
%ELSE (&tk - &knot1)**.666666666666; ;
%DO j=1 %TO &k2;
%LET t=&&knot&j;
&v7&j=max((&x-&t)/_kd_,0)**3+((&tk1-&t)*max((&x-&tk)/_kd_,0)**3
-(&tk-&t)*max((&x-&tk1)/_kd_,0)**3)/(&tk-&tk1)%STR(;);
%END;
%END;
%mend rcspline;
%macro rcspline(x,knot1,knot2,knot3,knot4,knot5,knot6,knot7,knot8,knot9,knot10, norm=2);
%LOCAL j v7 k tk tk1 t k1 k2;
%LET v7=&x; %IF %length(&v7)=8 %THEN %LET v7=%SUBSTR(&v7,1,7);
%*get no. knots, last knot, next to last knot;
%DO k=1 %TO 10;
%IF %QUOTE(&&knot&k)= %THEN %GOTO nomorek;
%END;
%LET k=11;
%nomorek: %LET k=%EVAL(&k-1); %LET k1=%EVAL(&k-1); %LET k2=%EVAL(&k-2);
%IF &k<3 %THEN %PUT ERROR: ❤️ knots given. no spline variables CREATEd.;
%ELSE %DO;
%LET tk=&&knot&k;
%LET tk1=&&knot&k1;
DROP _kd_; _kd_=
%IF &norm=0 %THEN 1;
%ELSE %IF &norm=1 %THEN &tk - &tk1;
%ELSE (&tk - &knot1)**.666666666666; ;
%DO j=1 %TO &k2;
%LET t=&&knot&j;
&v7&j=max((&x-&t)/_kd_,0)**3+((&tk1-&t)*max((&x-&tk)/_kd_,0)**3
-(&tk-&t)*max((&x-&tk1)/_kd_,0)**3)/(&tk-&tk1)%STR(;);
%END;
%END;
%mend rcspline;
**comparing to splines datasets from PROC LOGISTIC
**t1 from PROC LOGISTIC=t1 from below divided by 4-1=3;
DATA want; SET simulation;
%rcspline(t,1,2,3,4); *%rcspline(month,6,48,90);
RUN;