I created a macro that will check for empty columns of characters and either remove them from the original, or create a new dataset with the empty columns removed. It takes two optional arguments: the name of the dataset (by default, this is the most recently created dataset) and the suffix to indicate a new copy (set the suffix to edit the original).
It uses the proc freq parameter with the levels parameter and a custom format to define empty character columns. proc sql is then used to create a list of columns to be deleted and store them in a macro variable.
Here is the macro:
%macro delemptycol(ds=_last_, suffix=_noempty); option nonotes; proc format; value $charmiss ' '= ' ' other='1'; run; %if "&ds"="_last_" %then %let ds=&syslast.; ods select nlevels; ods output nlevels=nlev; proc freq data=&ds.(keep=_character_) levels ; format _character_ $charmiss.; run; ods output close; %local emptycols; proc sql noprint; select tablevar into: emptycols separated by ' ' from nlev where NNonMissLevels=0; quit; %if &emptycols.= %then %do; %put DELEMPTYCOL: No empty character columns were found in data set &ds.; %end; %else %do; %put DELEMPTYCOL: The following empty character columns were found in data set &ds. : &emptycols.; %put DELEMPTYCOL: Data set &ds.&suffix created with empty columns removed; data &ds.&suffix. ; set &ds(drop=&emptycols); run; %end; options notes; %mend;
Using examples:
data chardata(drop= j randnum); length char1-char5 $8.; array chars(5) char1-char5; do i=1 to 100; call missing(of char:); randnum=floor(10*ranuni(i)); do j=2 to 5; if (j-1)<randnum<=(j+1) then chars(j-1)="FOO"; end; output; end; run; %delemptycol(); %delemptycol(ds=chardata, suffix=);
source share