我目前在SAS工作,并以这种方式利用阵列:
Data Test;
input Payment2018-Payment2021;
datalines;
10 10 10 10
20 20 20 20
30 30 30 30
;
run;
我认为这会自动设置一个限制,无论是年初还是年底(如果我输入错了,请纠正我)
因此,如果我想说这是6月份的数据,并且付款将每9个月增加50%,我正在寻找一种方法让我的代码识别我的年份从6月底到下一年六月底
例如,如果我想说
Data Payment_Pct;
set test;
lastpayrise = "31Jul2018";
array payment:
array Pay_Inc(2018:2021) Pay_Inc: ;
Pay_Inc2018 = 0;
Pay_Inc2019 = 2; /*2 because there are two increments in 2019*/
Pay_Inc2020 = 1;
Pay_Inc2021 = 1;
do I = 2018 to 2021;
if i = year(pay_inc) then payrise(i) * 50% * Pay_Inc(i);
end;
run;
对于一个条目手动执行此操作对我来说是一件好事,但对于我的uni项目,我需要算法自己解决这些问题,并且我目前正在阅读intck,但任何帮助将不胜感激!< / p>
P.s。拥有一个可以创建以下内容的算法会很棒
Pay_Inc2019 Pay_Inc2020 Pay_Inc2021
1 2 1
或者,很高兴知道SAS如何为2018:2021设置阵列,它是假设在年底还是可以将其设置为年中?或者
答案 0 :(得分:1)
这是intnx()
函数的一个很好的用例。在对齐日期方面,intnx()
将是您最好的朋友。
在传统日历中,年份从01JAN
开始。在您的日历中,年份从01JUN
开始。这两个日期之间的差值恰好是6个月。我们想更改日期,以使年份从01JUN
开始。这样您就可以将日期中的年份作为一部分,并确定新日历中的年份。
data want;
format current_cal_year
current_new_year year4.
;
current_cal_year = intnx('year', '01JUN2018'd, 0, 'B');
current_new_year = intnx('year.6', '01JUN2018'd, 1, 'B');
run;
请注意,我们将current_new_year
移了一年。为了说明原因,让我们看看如果不将其转换一年会发生什么情况。
data want;
format current_cal_year
current_new_year year4.
;
current_cal_year = intnx('year', '01JUN2018'd, 0, 'B');
current_new_year = intnx('year.6', '01JUN2018'd, 0, 'B');
run;
current_new_year
显示的是2018年,但我们确实在2019年。一年中的5个月,这个值是正确的。从6月到12月,年份值将不正确。通过将其偏移一年,我们将始终具有与此日期值关联的正确年份。用一年中的不同月份查看它,您会发现年份部分在整个时间中都保持正确。
data want;
format cal_month date9.
cal_year
new_year year4.
;
do i = 0 to 24;
cal_month = intnx('month', '01JAN2016'd, i, 'B');
cal_year = intnx('year', cal_month, i, 'B');
new_year = intnx('year.6', cal_month, i+1, 'B');
year_not_same = (year(cal_year) NE year(new_year) );
output;
end;
drop i;
run;
答案 1 :(得分:1)
关于input Payment2018-Payment2021;
,没有自动假定年份或日历。数字2018和2021是numbered range list
在带编号的范围列表中,只要您不违反用户提供的名称规则并且数字是连续的,则可以以任何数字开头和以任何数字结尾。
2018年至2021年数字的含义由程序员决定。您声明变量对应于编号年份中的6月付款。
您必须使用9个月的步骤来迭代日期,并根据该日期所属的年份增加一个计数器。
示例代码
动态地适应排列的变量名。
data _null_;
array payments payment2018-payment2021;
array Pay_Incs pay_inc2018-pay_inc2021; * must be same range numbers as payments;
* obtain variable names of first and last element in the payments array;
lower_varname = vname(payments(1));
upper_varname = vname(payments(dim(payments)));
* determine position of the range name numbers in those variable names;
lower_year_position = prxmatch('/\d+\s*$/', lower_varname);
upper_year_position = prxmatch('/\d+\s*$/', upper_varname);
* extract range name numbers from the variable names;
lower_year = input(substr(lower_varname,lower_year_position),12.);
upper_year = input(substr(upper_varname,upper_year_position),12.);
* prepare iteration of a date over the years that should be the name range numbers;
date = mdy(06,01,lower_year); * june 1 of year corresponding to first variable in array;
format date yymmdd10.;
do _n_ = 1 by 1; * repurpose _n_ for an infinite do loop with interior leave;
* increment by 9-months;
date = intnx('month', date, 9);
year = year(date);
if year > upper_year then leave;
* increment counter for year in which iterating date falls within;
Pay_Incs( year - lower_year + 1 ) + 1;
end;
put Pay_Incs(*)=;
run;
递增计数器注释
此声明中有很多要解压的地方
Pay_Incs( year - lower_year + 1 ) + 1;
+ 1
将寻址数组元素增加1,并且是SUM Statement
的语法
变量+表达式
sum语句等效于使用SUM函数和RETAIN语句,如下所示:
retain variable 0; variable=sum(variable,expression);
year - lower_year + 1
计算数组base-1索引1..N,该索引处理命名范围列表pay_inc<lower_year>-pay_inc<upper_year>
Pay_Incs( <computed index> )
选择SUM
语句的变量