两个数据集之间的SAS迭代循环

时间:2017-08-30 10:59:25

标签: loops sas

我遇到了两种数据集的情况。

一个包含客户级别的默认记录,每行包含ID_customerdate_defaultamount_default等列,以及我需要的amount_default变量等可编辑的列变量我称之为left_default

第二项包括在客户级别进行的付款(如果有)以偿还这些默认值。该变量类似于默认值,如ID_customer,date_payment,amount_payment和一个等于amount_payment的变量,我需要它作为ediatable,我称之为left_paymnet

我想要的是代码迭代地遍历默认表的每一行,并且对于每个默认记录,如果同一客户进行任何付款,它在支付表中检查,支付日期大于或等于到默认值之一。

逻辑是oldeast默认获得优先支付给新的

如果有任何使用上述条件的付款,那么根据付款金额,我应该使用新列填充默认表,每个付款一列,直到默认金额完全覆盖。

同时,如果paymnet金额大于未支付的默认金额,那么我应该在支付部分剩余的默认金额后用剩余的付款金额更新left_payment列。

我认为举个例子比较简单。

我们说

table default

ID amount_default date_default left_defaullt  
1    5                01012015         5  
1    4                10012015         4  

table paymnet

ID amoutn_payment date_paymnet left_paymnet  
1  3                15122015         3  
1  6                18012016         6  

因此,在第一次迭代时,代码首先应关注第一个默认值5欧元,然后在支付表中查找付款应从第一行付款中获得3欧元,从第二行付款中获取2欧元。因此,在第一次迭代后,结果应为

default

ID amount_default date_default left_defaullt payment1 datepayment1  
1  5                01012015       2             3        15122015  
1  4                10012015       4  

payment

ID amoutn_payment date_paymnet left_paymnet  
1  3                15122015      0  
1  6                18012016      6  

由于第一次默认未完全支付,第二次迭代应创建以下结果

default

ID amount_default date_default left_defaullt pay1 date1   pay2  datet2  
1  5                01012015      0             3    15122015  2    18012016  
1  4                10012015      4  

payment

ID amoutn_payment date_paymnet left_paymnet  
1  3                15122015     0  
1  6                18012016     4  

作为完全支付的第一个默认值,然后迭代移动到第二个默认值

ID amount_default date_default left_defaullt pay1 date1   pay2  datet2  
1  5                01012015       0             3      15122015  2    18012016  
1  4                10012015       0             4       18012016  

payment

ID amoutn_payment date_paymnet left_paymnet  
1  3                15122015     0  
1  6                18012016     0  

因此,作为最终结果,我们知道每个默认值的每个部分何时已付款。

这涉及到SAS我想两个人通过两个数据集进行循环,但不确定如何将类似的代码组合在一起,就像在Web上看起来没有太多文档一样。

这是我正在处理的代码示例。很确定它有很多错误,但为了正确看待我的问题:

data tot_imp;                
   input contract $ nie $ account_type $ fecha date9. missing_pago;  
   format fecha date9.;
   datalines;         
1 xx cc 01SEP2017 5
1 xx cc 04SEP2017 4
;                          
run;  


data pagos;                
   input contract $ nie $ account_type $ fecha date9. remain_pago;  
   format fecha date9.;
   datalines;         
1 xx cc 09SEP2017 3
1 xx cc 12SEP2017 2
;                          
run;  



data tot_imp_el;
set tot_imp nobs=num1;

do k=1 to num1;

partial=0;

do i=1 to num;
set pagos (rename=(contract=con nie=nies account_type=type fecha=fechas)) nobs=num point=i;

if con=contract and nies=nie and fechas>=fecha and remain_pago>0 then do; /* if the pago date is later than the impago and the same pago has not been used for other impagos*/

if missing_impago-remain_pago<=0 then do; /* if the pago pays all the impago */

call symput("cc", partial);
call symput("pago","pago"&cc);
call symput("fecha","fecha_pago"&cc);

partial=partial+1;
&pago=missing_pago;
remain_pago=remain_pago-missing_pago; 
missing_pago=0 ;
&fecha=fechas;
drop con nies type fechas remaing_pago;

leave;

end;

else do;

call symput("cc", partial);
call symput("pago","pago"&cc);
call symput("fecha","fecha_pago"&cc);

partial=partial+1;
missing_pago=missing_pago-remain_pago;
&pago=remaing_pago;
&fecha=fechas;
remain_pago=0;

drop con nies type fechas remaing_pago;

end;

end;

end;

run;

1 个答案:

答案 0 :(得分:1)

将信息放在宽行中似乎是一种令人困惑的格式。如果你想要的基本上是每个ID的默认和支付的运行分类帐,我认为将数据保存在窄列中会更容易。例如,下面交错默认值和付款(按ID和日期),并创建一个运行余额:

data default;
  input ID amount date ddmmyy8.;
  format date date9.;
  cards;
1 5 01012015
1 4 10012015
;
run;

data payment;
  input ID amount date ddmmyy8.;
  format date date9.;
  cards;
1 3 15122015 3 
1 6 18012016 6
;

data want;
  set default (in=d) 
      payment (in=p)
  ;
  by id date;
  if first.id then balance=0;
  if d then do;
    type='Default';
    balance+-amount;
  end;
  if p then do;
    type='Payment';
    balance+amount;
  end;
run;

proc print data=want;
run;

返回:

Obs    ID    amount         date    balance     type

 1      1       5      01JAN2015       -5      Default
 2      1       4      10JAN2015       -9      Default
 3      1       3      15DEC2015       -6      Payment
 4      1       6      18JAN2016        0      Payment