在 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;
我希望通过将我的代码转换为数组和循环来提高我的代码效率。我正在处理的数据是这样开始的:
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;