/***********************************************************************************
输入参数:数据集(dataset),要分析的列colname,拐点要求跟前m个点比较和跟后n个点比较,
异类点相差r个季度,同类点差s个季度
输出参数:在原数据集加一列infP(1表示繁荣点,-1表示萧条点)得到数据集result
***********************************************************************************/
%macro Inflection_point(dataset,colname,m,n,r,s,result);
%do i=0 %to &n;
data A&i;
/*next0表点当前点,next1表下一点,next2表示后两点,类推*/
set &dataset(firstobs=%eval(&i+1) rename=(&colname=next&i));
time=_n_;
run;
%end;
proc sql noprint;
create table B as
select A0.time,A0.next0 %do i=1 %to &n;,A&i..next&i %end;
from A0 %do i=1 %to &n; left join A&i on A%eval(&i-1).time=A&i..time %end;;
quit;
proc sort data=B;
by time;
run;
/*求拐点*/
data result;
set B;
infP=0;
/*繁荣点,比前m个点大,比后n个点小*/
if time > &m %do i=1 %to &m; and next0 > lag&i(next0) %end;
%do i=1 %to &n; and next0 < next&i %end; then infP=1;
/*萧条点,比前m个点小,比后n个点大*/
if time > &m %do i=1 %to &m; and next0 < lag&i(next0) %end;
%do i=1 %to &n; and next0 > next&i %end; then infP=-1;
/*异类点相差r个季度*/
if 1=0 %do i=1 %to &r; or infP*lag&i(infP)=-1 %end; then infP=0;
/*同类点相差s个季度*/
if 1=0 %do i=1 %to &s; or infP*lag&i(infP)=1 %end; then infP=0;
run;
/*找出所有的繁荣点或萧条点*/
data B;
set result;
where infP <> 0;
run;
/*不能出现连续的同类点*/
data B;
set B;
if infP*lag1(infP)=1 then infP=.;
run;
/*将关键点与原表关联*/
proc sql noprint;
create table B0 as
select A0.*,b.infP
from A0 left join B on A0.time=B.time
;
quit;
/*获得输出数据集*/
data &result;
set B0;
rename next0=&colname;
drop time;
run;
%mend;
/*测试结果:得到1982年第四季与1991年第一季两个萧条点*/
data test;
input year quarter Country;
datalines;
1976 1 89940
1976 2 90590
1976 3 91438
1976 4 92011
1977 1 91463
1977 2 92771
1977 3 92471
1977 4 92259
1978 1 92566
1978 2 93683
1978 3 94691
1978 4 95773
1979 1 99199
1979 2 96862
1979 3 98110
1979 4 100138
1980 1 100044
1980 2 100353
1980 3 101271
1980 4 102884
1981 1 103104
1981 2 104878
1981 3 106716
1981 4 106666
1982 1 105576
1982 2 106250
1982 3 105580
1982 4 103917
1983 1 102947
1983 2 102681
1983 3 105714
1983 4 107765
1984 1 110318
1984 2 110740
1984 3 111683
1984 4 113249
1985 1 115045
1985 2 117700
1985 3 119099
1985 4 119640
1986 1 119924
1986 2 119356
1986 3 120527
1986 4 121628
1987 1 122987
1987 2 124421
1987 3 126317
1987 4 128875
1988 1 129745
1988 2 129875
1988 3 130841
1988 4 132488
1989 1 133925
1989 2 136603
1989 3 137990
1989 4 137914
1990 1 139487
1990 2 139467
1990 3 138074
1990 4 138544
1991 1 137478
1991 2 137187
1991 3 137058
1991 4 137261
1992 1 138686
1992 2 138721
1992 3 140237
1992 4 142554
1993 1 144140
1993 2 144945
1993 3 144717
1993 4 147738
1994 1 150609
1994 2 152270
1994 3 154199
1994 4 154638
1995 1 155793
1995 2 157427
1995 3 159585
1995 4 160646
1996 1 163415
1996 2 164013
1996 3 165798
1996 4 167658
1997 1 167607
1997 2 172035
1997 3 172686
1997 4 174772
1998 1 177241
1998 2 178559
1998 3 181468
1998 4 184730
1999 1 185752
1999 2 187678
1999 3 188571
1999 4 191512
2000 1 193451
2000 2 195511
2000 3 195938
2000 4 194343
2001 1 196011
2001 2 197726
2001 3 199840
2001 4 202383
2002 1 204371
2002 2 206948
2002 3 208488
2002 4 209118
2003 1 210585
2003 2 210996
2003 3 214129
2003 4 218368
2004 1 219746
2004 2 220954
2004 3 221963
2004 4 222918
2005 1 224209
2005 2 227478
2005 3 228329
2005 4 230057
2006 1 231410
2006 2 232590
2006 3 233280
;
run;
%Inflection_point(test,Country,2,2,2,5,result);
|