由于我想制作一个宏程序,用一个组中先前的非缺失值替换多个变量'缺失值,在此之前我需要使用多个变量对数据集进行排序,以便识别每个观察结果
我有一个测试数据集:
data temp2;
input countryname $1-5 +1 countrycode $7-8 +1 dev 1. +1 legal 1. +1 audit 1.;
datalines;
china 22 9 2 3
china 22 . . 3
china 22 7 3 .
china 21 4 . .
japan 13 3 . 1
japan 12 3 . .
japan 13 1 2 3
;
run;
正如您所看到的,我需要按国家/地区名称和国家/地区代码进行排序。并替换dev
legal
audit
缺失值。我尝试过像:
`%macro replace(dsetin=,dsetout=,idvars=,vars=);
%if &dsetout = %then %let dsetout = &dsetin;
%let char=_;
%do xi=1 %to %sysfunc(countw(&vars));
%let var = %scan(&vars,&xi);
%let _VARs_=%sysfunc(cat(&char,&var));
%end;
%let m=%sysfunc(countw(&vars));
%do yi=1 %to %sysfunc(countw(&idvars));
%let idvar = %scan(&idvars,&yi);
%let lagid = lag(&idvar);
%end;
%let n=%sysfunc(countw(&idvars));
proc sort data=&dsetin out=temp1;
by &idvars;
run;
data &dsetout;
set temp1;
by &idvars;
array id(&n)&idvar;
array lag(&n)&lagid;
array vara(&m)&var;
array vars(&m)&_VARs_;
do yi = 1 to &n;
if lag(yi)=id(yi) then do;
do xi= 1 to &m;
retain &_VARs_;
if not missing(&var) then &_VARs_ =&var;
else &var = &_VARs_;
end;
%end;
end;
drop of &_VARs_:;
run;
%mend replace;
%replace(dsetin=temp,dsetout=temp2,idvars=countryname countrycode,vars=DEV LEGAL AUDIT)`
这似乎乏味。 我无法处理这项任务。由于使用排序的变量的数量可能与“替换”的数量不同。变量。我希望宏可以应用于不同的场合。有时,使用sort的idvars数量可能会超过“替换”的数量。变量。有时前者可能比后者少。
希望它可以说明我的问题。感谢。
答案 0 :(得分:0)
这样的事情会产生预期的效果吗?
每当缺少在& vars中定义的变量时,它将被替换为它自己的滞后。
data temp;
input countryname $1-5 +1 countrycode $7-8 +1 dev 1. +1 legal 1. +1 audit 1.;
datalines;
china 22 9 2 3
china 22 . . 3
china 22 7 3 .
china 21 4 . .
japan 13 3 . 1
japan 12 3 . .
japan 13 1 2 3
;run;
%macro replace(dsetin,dsetout,idvars,vars);
%if &dsetout = %then %let dsetout = &dsetin;
proc sort data=&dsetin out=temp1;
by &idvars;
run;
data &dsetout;
set temp1;
*by &idvars;
array variables &vars;
array lags {%sysfunc(countw("&vars"))};
do i=1 to countw("&vars");
lags[i] = lag(variables[i]);
if variables[i]=. then variables[i] = lags[i];
end;
drop of lags: ;
drop i;
run;
%mend replace;
%replace(temp,,countryname countrycode,DEV LEGAL AUDIT);
答案 1 :(得分:0)
您可以使用UPDATE
语句来转发非缺失值。
因此我们可以创建这个宏来对数据进行排序,然后使用UPDATE语句来转发所选变量的非缺失值。通过添加额外的SET语句,我们可以确保任何其他变量不受UPDATE操作的影响。最后,我们需要一个OUTPUT语句来编写每个观察,否则只会写入BY组的最后一个观察。如果将VARS留空,我们甚至可以使其足够智能以更新所有非变量。
%macro replace(dsetin=,dsetout=,idvars=,vars=);
%if not %length(&dsetin) %then %let dsetin=&syslast;
%if not %length(&dsetout) %then %let dsetout=&dsetin ;
%if %length(&vars) %then %let vars=&idvars &vars;
proc sort data=&dsetin out=&dsetout;
by &idvars;
run;
data &dsetout ;
update &dsetout (obs=0) &dsetout (keep=&vars) ;
by &idvars ;
set &dsetout(drop=&vars);
output;
run;
%mend replace ;
现在让我们构建一些测试数据:
data have;
length countryname $5 countrycode $2 dev legal audit 8 ;
input countryname -- audit ;
datalines;
china 22 9 2 3
china 22 . . 3
china 22 7 3 .
china 21 4 . .
japan 13 3 . 1
japan 12 3 . .
japan 13 1 2 3
;;;;
运行宏并保留所有变量。然后只有一个。
%replace(dsetin=have,dsetout=want1,idvars=countryname countrycode,vars=);
%replace(dsetin=have,dsetout=want2,idvars=countryname countrycode,vars=legal);
然后比较结果。
proc compare data=want1 compare=want2 ;
run;