我遇到了两种数据集的情况。
一个包含客户级别的默认记录,每行包含ID_customer
,date_default
,amount_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;
答案 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