如何在 SAS 中从年终更改为年中

How to change from annual year end to annual mid year in SAS

我目前在 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.s。如果有一个算法可以创建以下内容,那就太好了

Pay_Inc2019 Pay_Inc2020 Pay_Inc2021
1           2           1

或者,很高兴知道 SAS 在为 2018:2021 设置数组时是如何工作的,它假设年末还是可以将其设置为年中或?

这是 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;

关于 input Payment2018-Payment2021; 没有年份或日历的自动假设。数字 2018 和 2021 是 numbered range list

的界限

In a numbered range list, you can begin with any number and end with any number as long as you do not violate the rules for user-supplied names and the numbers are consecutive.

数字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

    的语法

    variable + expression

    The sum statement is equivalent to using the SUM function and the RETAIN statement, as shown here: 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 语句的 变量