在 SAS 中使用上三角数组(挑战 +2 分)

Working with an upper-triangular array in SAS (challenge +2 Points)

我希望通过将我的代码转换为数组和循环来提高我的代码效率。我正在处理的数据是这样开始的:

ID    Mapping    Asset    Fixed    Performing    Payment 2017    Payment2018    Payment2019    Payment2020

1     Loan1      1        1        1              90             30             30             30
2     Loan1      1        1        0              80             20             40             20  
3     Loan1      1        0        1              60             40             10             10
4     Loan1      1        0        0              120            60             30             30
5     Loan2     ...       ...      ...            ...            ...            ...             ...

因此,对于每个 ID(基本上是按映射、资产、固定和执行排序的数据),我希望为付款方案建立一个配置文件。

第一个 ID 的付款向量如下所示:

PaymentVector1    PaymentVector2    PaymentVector3    PaymentVector4
1                 0.33              0.33              0.33

用公式表示

PaymentVector(I)=Payment(I)/Payment(1)

以上创建数组即可,如有需要可给出示例代码

接下来,假设每笔付款都被替换,即2018年支付30时,必须被替换,以此类推。

我正在寻找一个显示流出的配置文件(并且为了说明,但代码中不需要,在括号流入中)以显示付款的流动 - 对于 ID=1:

    Payment2017    Payment2018    Payment2019    Payment2020

17         (+90)            -30            -30           -30

18           N/A          (+30)            -10           -10

19          N/A           N/A              (+40)         -13.3

20         N/A             N/A             N/A          (+53.3)

因此,如果您向前看,可以将行视为现在的年份,而列表示即将到来的年份。

因此,在 2019 年,查看 2017 年和 2018 年要支付的金额是 N/A,因为这些付款是过去的/现在无法支付。

至于2018年,看看2019年要交的钱,你要交现在钱的三分之一,所以-10。

我一直在努力将这个数据集逐行转换为数组,但肯定有一种使用数组的更快方法:

到目前为止我使用的代码如下所示:

Data Want;
Set Have;

Array Vintage(2017:2020) Vintage2017-Vintage2020;
Array PaymentSchedule(2017:2020) PaymentSchedule2017-PaymentSchedule2020;
Array PaymentVector(2017:2020) PaymentVector2017-PaymentVector2020;
Array PaymentVolume(2017:2020) PaymentVolume2017-PaymentVolume2020;

do i=1 to 4;

PaymentVector(i)=PaymentSchedule(i)/PaymentSchedule(1);

end;

我明天会添加代码...但是无论如何代码都不起作用。

您已经使用 2017:2020 为数组编制了索引,但随后尝试使用 1 到 4 索引来使用它们。那行不通,你需要保持一致。

Array PaymentSchedule(2017:2020) PaymentSchedule2017-PaymentSchedule2020;
Array PaymentVector(2017:2020) PaymentVector2017-PaymentVector2020;


do i=2017 to 2020;

PaymentVector(i)=PaymentSchedule(i)/PaymentSchedule(2017);

end;
data have;
input
ID    Mapping $  Asset    Fixed    Performing    Payment2017    Payment2018    Payment2019    Payment2020; datalines;
1     Loan1      1        1        1              90             30             30             30
2     Loan1      1        1        0              80             20             40             20  
3     Loan1      1        0        1              60             40             10             10
4     Loan1      1        0        0              120            60             30             30

data want(keep=id payment: fraction:);
  set have;
  array p payment:;
  array fraction(4); * track constant fraction determined at start of profile;
  array out(4); * track outlay for ith iteration;

  * compute constant (over iterations) fraction for row;
  do i = dim(p) to 1 by -1;
    fraction(i) = p(i) / p(1);
  end;

  * reset to missing to allow for sum statement, which is <variable> + <expression>;
  call missing(of out(*));

  out(1) = p(1);
  do iter = 1 to 4;
    p(iter) = out(iter);
    do i = iter+1 to dim(p);
      p(i) = -fraction(i) * p(iter); 
      out(i) + (-p(i));  * <--- compute next iteration outlay with ye olde sum statement ;
    end;
    output;
    p(iter) = .;
  end;

  format fract: best4. payment: 7.2;
run;