Currently you are looping 6000*nrows, but if you keep a track of the columns already disqualified there is no need to consider them again. Here is using a hash iterator to do it. Plus it makes the drop step a bit easier. Should be n^2 complexity vs n * (n+1)/2 average case complexity now. I've created some dummy data and moved the data output step outside of the loop. I got 30 seconds vs 0.18. data have;
array c[6000] $1 _a1-_a6000;
do _n_=1 to 10000;
do i=1 to dim(c);
c[i]=ifC(ranuni(123)>.99 and i>3,'?','x');;
end;
output;
end;
run;
data _null_;
set have;
run;
data _null_;
set have end=last;
array _a{*} $ _character_;
length name $12;
if _n_ = 1 then do;
call missing(idx, name);
declare hash miss (ordered:"a");
miss.definekey("idx");
miss.definedata('idx','name');
miss.definedone();
declare hiter iter('miss');
do idx=1 to dim(_a);
miss.add(key:idx,data:idx,data:vname(_a[idx]));
end;
end;
rc=iter.first();
do while (rc = 0);
if _a[idx] eq '?' then do;
_x=idx;
rc=iter.next();
miss.remove(key:_x);
end;
else rc=iter.next();
end;
if last then miss.output(dataset:'keep');
run;
proc sql noprint;
select name into :mv_mc separated by ',' from keep;
quit;
%put Note: Columns that will be discarded are &mv_mc;
proc sql noprint;
alter table have drop &mv_mc.;
quit;
... View more