forked from friendly/SAS-macros
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cusum.sas
77 lines (67 loc) · 2.15 KB
/
cusum.sas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
*---------------------------CUSUM------------------------------*
| This IML routine computes recursive residuals and outputs |
| their cumulative sum and ss (called cusum and cusumss) to a |
| sas data set to be plotted. The plot should show if the |
| regression parameters change over time. |
| From: Brown,Durbin, and Evans, "Techniques for testing the |
| constancy of regression relationships over time", |
| JRSS B V37, P149 (1975). |
*------------------------------------------------JPS--25OCT79--*;
%macro cusum(
data=_last_, /* name of input data set */
yvar=, /* response variable */
xvars=, /* predictor variables */
out=cusum /* name of output data set */
);
proc iml;
use &data;
read all var {&xvars} into x[ colname=xname ];
read all var {&yvar} into y[ colname=yname ];
close &data;
*--------cusum----------;
n=nrow(x);
p=ncol(x);
x = j(n,1,1) || x;
p1=p+1;
*---first p+1 observations---;
z=x[ 1:p1, ];
yy=y[ 1:p1, ];
xy=t(z)*yy;
ixpx=inv(t(z)*z);
b=ixpx*xy;
r=y[ p1, ]-z[ p1, ]*b;
*---recursion until n---;
start recurse;
do i=p+2 to n;
xi=x[ i, ]; yi=y[ i, ];
xy=xy+t(xi)*yi;
ixpx=invupdt(ixpx,xi); /* update inverse matrix */
b=ixpx*xy; /* new coefficients */
r=r//(yi-xi*b); /* current residual */
end;
finish;
run recurse;
*---print estimates---;
print "Final parameter estimates", b /;
print "Inverse XPX matrix", ixpx /;
*---form lower triangle of ones---;
m=n-p;
tri= (1:m)`*repeat(1,1,m) >= repeat(1,m,1)*(1:m) ;
*---form csum and csumss---;
cusum=tri*r;
cusumss=tri*(r#r);
*---output to dataset---;
rnames=xname || yname || { n residual cusum cusumss };
x= x[ p1:n, 2:p1 ] || y[ p1:n ];
x= x || (p1:n)` || r || cusum || cusumss;
print x [ colname=rnames ] /;
create &out from x [ colname=rnames ];
append from x;
quit;
data &out;
set &out;
label
residual='Recursive residual'
cusum='CUSUM value'
cusumss ='Cumulative SS';
%mend;