BookmarkSubscribeRSS Feed
Jade_SAS
Pyrite | Level 9

Hi All,

 

   I found a macro in the forum to calculate the missing data percentage for each variable in the data set. I tried it and it works, but for some reason the last variable in the data set will be get rid of, I wonder how to fix this macro. Is there anybody can help? Thank you!

   1) Macro

%macro missing_data(library=,dataset=,xoutdataset=);

 

proc sql noprint;

select name into :allvars separated by " " from dictionary.columns

where libname="%upcase(&library.)" and memname="%upcase(&dataset.)";

 

quit;

proc sql noprint;

create table &xoutdataset. as

 

select

%let firstspace=%sysfunc(find(&allvars.,%str( )));

%do %while (&firstspace.>0);

%let var=%substr(&allvars.,1,&firstspace.);

sum(missing(&var.))/count(*) as &var.,

%let allvars=%substr(&allvars.,&firstspace.);

%let firstspace=%sysfunc(find(&allvars.,%str( )));

%end;

'Y' as done_successfully

from &library..&dataset.;

 

quit;

%mend missing_data;

 

%missing_data(library=sashelp,dataset=class,xoutdataset=outfile);

 

 

   2) The output variable list after macro used: 

  Name Sex Age Height done_successfully

 

   3) The variable list in the data set:

   Name Sex Age Height Weight

 

Compare 2) and 3), we can see the weight variable is gone after using the macro. I wonder how this macro be fixed to include every variables in the data set.

 

Thanks,

Jade

5 REPLIES 5
PaigeMiller
Diamond | Level 26

Something in the looping over the variables gets screwed up by this code. I will leave it to others to figure out exactly where the error is (if understanding the exact error is of interest). However, the code below doesn't have this problem

 

%macro missing_data(library=,dataset=,xoutdataset=);
    proc sql noprint;
        select name into :allvars separated by " " from dictionary.columns
        where libname="%upcase(&library.)" and 
        memname="%upcase(&dataset.)";
    quit;
    proc sql noprint;
        create table &xoutdataset. as select
        %do i=1 %to %sysfunc(countw(&allvars));
              %let var=%scan(&allvars,&i,%str( ));
              sum(missing(&var.))/count(*) as &var. 
              %if &i<%sysfunc(countw(&allvars)) %then , ;
        %end;
        from &library..&dataset.;
    quit;
%mend missing_data;

 

--
Paige Miller
Astounding
PROC Star

There is no blank space at the end of &ALLVARS, so the FIND function can't locate one to determine when the last variable name ends.

 

Consider modifying here:

 

%let allvars=%substr(&allvars.,&firstspace.+1);

%let firstspace=%sysfunc(find(%str(&allvars. ),%str( )));

 

The first change removes the leading blank from &ALLVARS.  Then the second change adds a blank to the end of &ALLVARS.  (Not sure that the first change is required, but you can test it and report back to the group.)

Ksharp
Super User

Try this code.

 

data have;
 set sashelp.class;
 call missing(age ,sex);
run;

/*firstly get variable name*/
proc transpose data=have(obs=0) out=vname;
var _all_;
run;
/*then know  missing percent*/
proc sql noprint;
select catx(' ','nmiss(',_name_,')/count(*) as',_name_) into :vnames separated by ','
from vname;
create table want as
select &vnames from have;
quit;
Kurt_Bremser
Super User

When you use %substr, the resulting macro variable has no blanks for padding (as opposed to what you have in a data step), so the resulting value for firstchar is zero when there's one item left.

The way the loop is built, someone out-thunk him/herself  when working around the non-existent %countw() function.

The proper method for such loops has been posted by @PaigeMiller: use %sysfunc(countw()) and a simple iterative do loop.

And support my suggestion for the introduction of a %countw macro function:

https://communities.sas.com/t5/SASware-Ballot-Ideas/Macro-equivalent-for-countw/idi-p/409066

 

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

How to connect to databases in SAS Viya

Need to connect to databases in SAS Viya? SAS’ David Ghan shows you two methods – via SAS/ACCESS LIBNAME and SAS Data Connector SASLIBS – in this video.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 5 replies
  • 1518 views
  • 4 likes
  • 5 in conversation