【发布时间】:2018-03-19 10:31:56
【问题描述】:
我一直在使用一个在最近更新数据之前一直运行良好的数组。一个示例数据集可以构造如下:
Data Have;
input Fixed_or_floating $ ID Vintage Base2017 Base2018 Base2019 Base2020 dateoflastrepricing repricingfrequency;
datalines;
FLT 1 2017 0 0 0 0 2011 2
FLT 1 2018 0 0 0 0 2011 2
FLT 1 2019 0 0 0 0 2011 2
FLT 1 2020 0 0 0 0 2011 2
FLT 2 2017 0 0 0.1 0.1 2014 1
FLT 2 2018 0 0 0.1 0.1 2014 1
FLT 2 2019 0 0 0.1 0.1 2014 1
FLT 2 2020 0 0 0.1 0.1 2014 1
FIX 3 2017 0.1 0.3 0.2 0.1 2016 3
FIX 3 2018 0.1 0.3 0.2 0.1 2016 3
FIX 3 2019 0.1 0.3 0.2 0.1 2016 3
FIX 3 2020 0.1 0.3 0.2 0.1 2016 3
FLT 4 2017 0 0 0.1 0 2016 1
FLT 4 2018 0 0 0.1 0 2017 1
FLT 4 2019 0 0 0.1 0 2017 1
FLT 4 2020 0 0 0.1 0 2017 1
;
run;
对象是创建一个数组,当年份等于基准年(取决于某些限制)时,该数组将标志 =1,如下所示:
对于固定资产来说很简单,当年份 = 基准年时,标志只需要 = 1
Flag2017 Flag2018 Flag2019 Flag2020
1 0 0 0
0 1 0 0
0 0 0 1
用于在当年重新定价时浮动 flag=1。例如,如果上一次重新定价是在 2011 年,并且每两年重新定价一次,那么它会在 2011、2013、2015、2017、2019、2021 年重新定价。那么对于 2018 年,它会在 2 年内重新定价。然后是 2019 年,在 2 年内重新定价。我只标记 2017-2020 年,所以我会寻找这样的表格
Vintage Flag2017 Flag2018 Flag2019 Flag2020
2017 1 0 1 0
2018 0 0 0 1
2019 0 0 0 0
2020 0 0 0 0
我以前使用的代码是:
data want;
set have;
*arrays for years and flags;
array _Base(2014:2022) Base2014-Base2022;
array _flag(2017:2022) flag2017-flag2022;
*loop over array;
if upcase(FixedorFloating)="FIX"
then do i=2017 to 2020;
/*check if year matches year in variable name*/
if put(Vintage, 4.) = compress(vname(_Base(i)),, 'kd')
then _flag(i)=1;
end;
else if upcase(fixedorfloating)="FLT" and repricingfrequency=2
then do i=2017 to 2020;
if put(Vintage, 4.) = compress(vname(_Base(i)),, 'kd')
then _flag(i)=1;
else if put(Vintage, 4.) = compress(vname(_Base(i-2)),, 'kd')
then _flag(i)=1;
end;
else if upcase(fixedorfloating)="FLT" and repricingfrequency=1
then do i=2017 to 2020;
if put(Vintage, 4.) <= compress(vname(_Base(i)),, 'kd')
then _flag(i)=1;
end;
else if upcase(fixedorfloating)="FLT" and repricingfrequency>=3
then do i=2017 to 2020;
if put(Vintage, 4.) = compress(vname(_Base(i)),, 'kd')
then _flag(i)=1;
else if put(Vintage, 4.) = compress(vname(_Base(i-3)),, 'kd')
then _flag(i)=1;
end;
drop i;
run;
我已经意识到,如果年份是偶数还是奇数,我需要添加一个捕获,稍后我会添加这个。我的问题是为什么会出现这个错误,数组应该足够大以进行操作?
ERROR: Array subscript out of range at line 87 column 42.
87 if put(Vintage, 4.) = compress(vname(_Base(i)),, 'kd')
88 then _flag(i)=1;
编辑:附加日志
Fixed_or_floating=FLT ID=1 Vintage=2017 Base2017=0 Base2018=0 Base2019=0 Base2020=0
dateoflastrepricing=2011 repricingfrequency=2 Base2014=. Base2015=. Base2016=. Base2021=.
Base2022=. flag2014=. flag2015=. flag2016=. flag2017=. flag2018=. flag2019=. flag2020=. flag2021=.
flag2022=. i=2017 _ERROR_=1 _N_=1
【问题讨论】:
-
我认为您的日志中缺少一些有趣的部分,包括
Base2014=some value 和ERROR=1 -
当然,我会在几秒钟内添加一个
-
好像没有2017年的基数?很奇怪。编辑:我看到了
-
您发布的代码有效(在修复了一个变量名之后)。我会在程序中查找是否缺少分号或其他导致它运行的数据步骤与您想象的不同的东西。
-
@tom - 我发现代码在删除 else if 后仍然有效,这真的很奇怪,我会再次检查它,看看是否可以将 else if 放回去
标签: arrays loops for-loop sas sas-studio