I was trying to generate a list of variables, whose names are stored in a macro &varsnew. The value of the 1st (2nd, 3rd, etc.) of these variables equals (a) the 1st (2nd, 3rd, etc.) of another list of variables, whose names are stored in another macro &varsold, if the variable in &varsold is not missing, or (b) 0, if the variable in &varsold is missing.
The following code works fine, where I use if-then clause to define variables in &varsnew.
%macro coal;
data DS;
set DS;
%do i=1 %to %sysfunc(countw(&varsold.));
if %scan(&varsold.,&i.)<=.z then %scan(&varsnew.,&i.)=0 ;
else %scan(&varsnew.,&i.)=%scan(&varsold.,&i.);
%end;
run;
%mend;
%coal;
However, if I use the coalesce function to define variables in &varsnew, as in the following, then the code does not work. I am puzzled.
%macro coal;
data DS;
set DS;
%do i=1 %to %sysfunc(countw(&varsold.));
%scan(&varsnew.,&i.)= %sysfunc(coalesce(%scan(&varsold.,&i.),0));
%end;
run;
%mend;
%coal;
答案 0 :(得分:3)
Your two loops are doing two different things. The first one is checking if a data set variable is missing and the second is checking if the lists of variable names have the same number of entries. Turn on MPRINT option so you can see what SAS code your macro is generating.
The first one will generate code like:
if OLD1<= .Z then NEW1=0; ELSE NEW1=OLD1;
The second one will generate code like:
NEW1=OLD1;
NEW2=OLD2;
NEW3=0;
You probably want this instead.
%do i=1 %to %sysfunc(countw(&varsold));
%scan(&varsnew,&i)=coalesce(%scan(&varsold,&i),0);
%end;
Or just
%do i=1 %to %sysfunc(countw(&varsold));
%scan(&varsnew,&i)=sum(%scan(&varsold,&i),0);
%end;
Or even better forget the macro logic and just write the whole thing using simple SAS statements.
array _new &varsnew ;
array _old &varsold ;
do i=1 to dim(_new);
_new(i)=sum(_old(i),0);
end;