我正在尝试运行此代码
data swati;
input facility_id$ loan_desc : $50. sys_name :$50.;
cards;
fac_001 term_loan RM_platform
fac_001 business_loan IQ_platform
fac_002 business_loan BUSES_termloan
fac_002 business_loan RM_platform
fac_003 overdrafts RM_platform
fac_003 RCF IQ_platform
fac_003 term_loan BUSES_termloan
;
proc contents data=swati out=contents(keep=name varnum);
run;
proc sort data=contents;
by varnum;
run;
data contents;
set contents ;
where varnum in (2,3);
run;
data contents;
set contents;
summary=catx('_',name, 'summ');
run;
data _null_;
set contents;
call symput ("name" || put(_n_ , 10. -L), name);
call symput ("summ" || put (_n_ , 10. -L), summary);
run;
options mlogic symbolgen mprint;
%macro swati;
%do i = 1 %to 2;
proc sort data=swati;
by facility_id &&name&i.;
run;
data swati1;
set swati;
by facility_id &&name&i.;
length &&summ&i. $50.;
retain &&summ&i.;
if first.facility_id then do;
&&summ&i.="";
end;
if first.&&name&i. = last.&&name&i. then &&summ&i.=catx(',',&&name&i., &&summ&i.);
else if first.&&name&i. ne last.&&name&i. then &&summ&i.=&&name&i.;
run;
if last.facility_id ;
%end;
%mend;
%swati;
此代码将创建两个新变量 loan_desc_summ 和 sys_name_summ ,其中包含一行中所有loan_desc的值,以及由逗号示例分隔的一行中的sys_names(term_loan ,business_loan),(RM_platform,IQ_platform)但是如果客户只有一个loan_desc,那么loan_summ只应该有两次。
运行do循环时的问题是运行此代码后,我只获取了sys_name_summ而不是loan_desc_summ的数据集。我希望数据集包含所有五个变量 facility_id,loan_desc,sys_name,loan_desc_summ,sys_name_summ。
你能不能帮我找出do循环中是否有问题?
答案 0 :(得分:0)
您的循环始终以相同的输入数据集(swati
)开始并生成新的数据集(SWATI1
)。所以只有最后一次循环才会产生任何影响。每个循环都需要从上一次运行的输出开始。
您还需要修复逻辑以消除重复项。
例如,您可以将宏更改为:
%macro swati;
data swati1;
set swati;
run;
%do i = 1 %to 2;
proc sort data=swati1;
by facility_id &&name&i.;
run;
data swati1;
set swati1;
by facility_id &&name&i ;
length &&summ&i $500 ;
if first.facility_id then &&summ&i = ' ' ;
if first.&&name&i then catx(',',&&summ&i,&&name&i);
if last.facility_id ;
run;
%end;
%mend;
如果您只使用数组,那么您的程序可能会小很多。
data want ;
set have ;
by facility_id ;
array one loan_desc sys_name ;
array two $500 loan_desc_summ sys_name_summ ;
retain loan_desc_summ sys_name_summ ;
do i=1 to dim(one);
if first.facility_id then two(i)=one(i) ;
else if not findw(two(i),one(i),',','t') then two(i)=catx(',',two(i),one(i));
end;
if last.facility_id;
drop i loan_desc sys_name ;
run;
如果您想使其更灵活,可以将变量名称列表放入宏变量中。
%let varlist=loan_desc sys_name;
然后,您可以轻松生成新名称列表。
%let varlist2=%sysfunc(tranwrd(&varlist,%str( ),_summ%str( )))_summ ;
然后,您可以使用ARRAY
,RETAIN
和DROP
语句中的宏变量。