2016-06-20 178 views
0

这是我第一次在这个论坛上提问。我已经使用SAS/Proc SQL大约4年了,但我不是一个代码Jedi,所以请给出详细的答案,并且对于数组来说是相当新的,所以请原谅,如果我的问题没有详细解释。一般来说,我是100%舒适的建筑/使用简单的阵列。但我有一个非常具体的挑战,我无法弄清楚......难以置信的话,所以这可能会长时间的啰嗦,但这里...SAS数组/循环迭代变量

对于基本了解我想要完成的事情,它有点类似于第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 [迭代参考。我也试过&我基于另一个在线用户收到的解决方案似乎是类似的问题。该逻辑是有道理的,似乎像它应该在理论工作,但不...

因此,我们不得不手动操作和每个代码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); 

好像有应该是一个简单的解决方案,但我们无法弄清楚。在此先感谢您提供的任何帮助。

+1

分开回答你的问题:我会*强烈*鼓励你重新配置你的数据结构。如果您在这里每个时间段有一行,SAS(以及其他任何非矩阵语言)将会使_Far_更好。 – Joe

+0

数组中包含什么?余额?利益?不同的月份?为什么不同长度?请张贴一小段数据。我看到一个聚合的SQL查询解决方案。 – Parfait

+0

好问题...有点难以回答,因为我的贷款比较例子不是一个完美的比较,它在细节上有点混乱。输出=剩余余额(出局193 mos); Array1 =总损失$(193mos); Array2 =收益(97mos); Array3 =定期付款(97mos)。 阵列是不同的长度,因为还有其他事件发生在投资组合的生命... – CraigD

回答

1

当编译数据步骤时,会计算像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; 
+0

哦,我完全误读他在那里做什么。好点子。 – Joe

+0

您可能仍然希望检查数组2/3的模糊,因为它们比数组短。 – Joe

+0

因此,为每个输入数组分别做单独的循环。 – Tom

2

因此,你有三组变量与原则调整。您有一个起始余额,并且您想通过应用调整来计算各种中间余额。

首先通过使数组具有相同的大小来简化您的问题。新的变量将会丢失。如果您确实有这些变量,但不想将它们包含在计算中,请将它们从输入数据集中删除。请注意,如果您有名为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; 
+0

谢谢Tom。几乎正是我想出来的,结果又回到了旧代码中......非常感谢你的帮助! – CraigD