【问题标题】:SAS array/loop iteration variableSAS 数组/循环迭代变量
【发布时间】:2016-06-20 16:02:58
【问题描述】:

这是我第一次在这个论坛上提问。我已经使用 SAS/Proc SQL 大约 4 年了,但我不是代码绝地,所以请给出详细的答案,并且对数组相当陌生,所以如果我的问题没有详细/解释,请原谅。一般来说,我对构建/使用简单的数组感到 100% 的舒适。但是我有一个非常具体的挑战,我无法弄清楚......很难用语言表达,所以这可能会变得冗长但这里......

对于我要完成的工作的基本理解,它有点类似于简单的贷款摊销,其中第 1 个月的余额是原始贷款金额,比如说 10,000 美元,第 2 个月的余额是 orig_ln_amt 减去任何新的本金/利息支付减去任何额外的付款,可以说是 9500 美元,第 3 个月的结果是 9000 美元等等。对于 1 个帐户来说很容易,但我正在构建一个数组,当所有活动帐户汇总在一起时,我实际上会给出预测的总剩余余额未来一个月,所以我使用的数组大小每个月都会根据帐户的年龄而变化。

下面是一些我希望可以工作的示例代码:

DATA SAMPLE;
  SET INPUT_DATA; 'HAS EACH OF THE 3 INPUT ARRAYS LAID OUT SIDE BY SIDE BY SIDE
  ARRAY_ONE {193} ARRAY_ONE1-ARRAY_ONE193; 
  ARRAY_TWO {97} ARRAY_TWO1-ARRAY_TWO97;
  ARRAY_THREE {97} ARRAY_THREE1-ARRAY_THREE97; 
  OUTPUT_ARRAY {193} OUTPUT_ARRAY1-OUTPUT_ARRAY193; 'PORTFOLIO BALANCE EACH FUTURE MONTH
  DO I = 1 TO 193;
    OUTPUT_ARRAY[I] = sum(of ARRAY_ONE[I]-ARRAY_ONE193) - sum(of ARRAY_TWO[I]-ARRAY_TWO97) - sum(of ARRAY_THREE[I]-ARRAY_THREE97);
  END;
RUN;

问题是 SAS 不喜欢数组计算中的 [I[ 迭代引用。我也尝试过 &I 基于另一个在线用户收到的似乎是类似问题的解决方案。这个逻辑是有道理的,看起来它应该在理论上可行,但不是......

因此,我们不得不手动操作和编码 193 个计算中的每一个:

OUTPUT_ARRAY1 = sum(of ARRAY_ONE1-ARRAY_ONE193) - sum(of ARRAY_TWO1-ARRAY_TWO97) - sum(of ARRAY_THREE1-ARRAY_THREE97);
OUTPUT_ARRAY2 = sum(of ARRAY_ONE2-ARRAY_ONE193) - sum(of ARRAY_TWO2-ARRAY_TWO97) - sum(of ARRAY_THREE2-ARRAY_THREE97);
  ...
OUTPUT_ARRAY97 = sum(of ARRAY_ONE97-ARRAY_ONE193) - sum(of ARRAY_TWO97-ARRAY_TWO97) - sum(of ARRAY_THREE97-ARRAY_THREE97);
OUTPUT_ARRAY98 = sum(of ARRAY_ONE98-ARRAY_ONE193);
  ...
OUTPUT_ARRAY193 = sum(of ARRAY_ONE193-ARRAY_ONE193);

似乎应该有一个简单的解决方案,但我们无法弄清楚。提前感谢大家可以提供的任何帮助。

【问题讨论】:

  • 与回答您的问题分开:我会强烈鼓励您重新制定数据结构。如果您在此处每个时间段有一行,则 SAS(和任何其他非矩阵语言)会远远做得更好。
  • 数组中包含什么?余额?兴趣?不同月份?为什么长度不一样?请发布数据的sn-p。我看到了一个聚合 SQL 查询解决方案。
  • 好问题...有点难以回答,因为我的贷款摊销示例不是一个完美的比较,而且在细节上有点混乱。输出 = 剩余余额(输出 193 个月); Array1 = 总损失 $ (193mos); Array2 = 收益(97mos); Array3 = 定期付款 (97mos)。数组的长度不同,因为在投资组合的生命周期中还会发生其他事件...

标签: arrays loops variables sas iteration


【解决方案1】:

所以你有三组对原则进行调整的变量。您有一个起始余额,并且您想通过应用调整来计算各种中间余额。

首先通过使数组大小相同来简化您的问题。新变量将丢失。如果您实际上有这些变量,但只是不想将它们包含在计算中,则将它们从输入数据集中删除。请注意,如果您有名为 ONE1 到 ONE193 的变量,那么您可以通过使用此语句 array one(193); 创建一个名为 ONE 的数组来使用这些变量。

第二次简化你的算术以更接近你的问题描述。在我看来,算法是下一个余额是基于前一个余额减去所有调整。包括零以处理所有调整都缺少值的情况。

%let n=193;
data want;
  set have;
  array one (&n);
  array two (&n);
  array three (&n);
  array balance Initial_balance balance1-balance&n;
  do i=1 to dim(balance)-1;
    balance(i+1)=balance(i)-sum(0,one(i),two(i),three(i));
  end;
run;

【讨论】:

  • 谢谢汤姆。这几乎正​​是我想出的,结果与旧代码联系在一起......非常感谢您的帮助!
【解决方案2】:

VAR1-VAR20 这样的变量列表是在编译数据步骤时计算的。您尝试使用ARRAY[I]-variable193 作为变量列表不会成功。只需使用另一个 DO 循环即可。

DO I = 1 TO dim(output_array);
  output_array(i)=0;
  DO J=I to dim(array_one);
    output_array(i)= sum(output_array(i),array_one(j));
  END;
  DO J=I to dim(array_two);
    output_array(i)= sum(output_array(i),array_two(j));
  END;
  DO J=I to dim(array_three);
    output_array(i)= sum(output_array(i),array_three(j));
  END;
END;

【讨论】:

  • 您可能仍需要检查数组二/三的暗度,因为它们比数组一短。
  • 所以为每个输入数组单独的 do 循环。
  • 无法让这个双循环逻辑工作,但我想我可能已经弄明白了。
  • output_array1= &begin_bal;我 = 2 到 85; output_array[I]= output_array[I-1] - ((sum (of array_one[I-1]))+ (sum (of array_two[I-1]))+ (sum (of array_three[I-1]) ));做 i = 86 到 97; output_array[I]= output_array[I-1] - ((sum (of array_one[I-1]))+ (sum (of array_two[I-1]))); i = 98 到 193; output_array[I]= output_array[I-1] - ((sum (of array_one[I-1]));
  • 数组大小每个月都会因为定期老化而变化,公式在第86点和第98点因为底层数据而变化。抱歉,我知道我的例子并不准确,但我认为它会为每个人指明正确的方向......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-13
  • 2022-01-23
  • 1970-01-01
相关资源
最近更新 更多