正如标题中所建议的那样,我想删除所有空列\变量(其中所有记录都为空或等于null或“”),以便减少以后执行的时间成本。
详细方案:
我有一个包含1000列的数据集(),其中一些\很多都是空的。现在我想创建一个新的数据集,我需要在以前的数据集的某些条件下添加列。
data new;
set old;
if oldcol1 ne "" then newcol1='<a>'||strip(oldcol1)||'</a>';
end;
if oldcol2 ne "" then newcol2='<a>'||strip(oldcol2)||'</a>';
end;
...
...;
drop oldcol1 oldcol2.....oldcol1000;
run;
由于以下原因,执行需要相当长的时间:
旧列的数量巨大
实际上我需要在另一个数据集中做一个循环来设置 oldcol
ColNumber
1
2
3
...
1000
因此,您可以想象在搜索,查找和设置值方面要执行多少次。
因此,我认为减少时间成本的一种方法是首先删除所有空列。但是,关于优化算法的任何输入也都受到欢迎。
由于
答案 0 :(得分:2)
这是一个通用宏,可用于生成源数据集中的空列列表,然后可以将其传递给drop语句。它使用proc格式和proc freq,因此速度相对较快。
%macro findmiss(ds,macvar);
%local noteopt;
%let noteopt=%sysfunc(getoption(notes));
option nonotes;
*ds is the data set to parse for missing values;
*macvar is the macro variable that will store the list of empty columns;
%global &macvar;
proc format;
value nmis .-.z =' ' other='1';
value $nmis ' '=' ' other='1';
run;
ods listing close;
ods output OneWayFreqs=OneValue(
where=(frequency=cumfrequency
AND CumPercent=100));
proc freq data=&ds;
table _All_ / Missing ;
format _numeric_ nmis.
_character_ $nmis.;
run;
ods listing;
data missing(keep=var);
length var $32.;
set OneValue end=eof;
if percent eq 100 AND sum(of F_:) < 1 ;
var = scan(Table,-1,' ');
run;
proc sql noprint;
select var into: &macvar separated by " "
from missing;quit;
option ¬eopt.;
%mend;
以下是您可以使用它的方法:
%findmiss(old,droplist); /*generate the list of empty columns */
data new;
set old(drop=&droplist);
run;
答案 1 :(得分:1)
我同意proc转置是一个好主意:
proc transpose data=old out=temp;
var _ALL_;
run;
data _NULL_;
set temp end=eof;
array cols {*} COL: ;
do i = 1 to dim(cols);
cols[i]=ifn((strip(cols[i])=" " or strip(cols[i])="."),0,1);
end;
if sum(of COL:)=0 then
call symput("dropvars", catx(" ",symget("dropvars"),_NAME_));
run;
data new; set old (drop=&dropvars); run;
答案 2 :(得分:0)
这样的东西?
data work.temp1;
attrib idcol length=8;
set work.old;
idcol=_n_;
run;
proc transpose data=work.temp1 out=work.temp2 name=varname;
var oldcol1-oldcol1000;
by idcol;
run;
proc sql;
create table work.temp3 as
select distinct varname from work.temp2 where not missing(col1);
quit;
data _null_;
set work.temp3 end=lastrec;
attrib nvarname length=$32;
if _n_=1 then do;
call execute('data work.new;');
call execute('set work.old;');
end;
nvarname = 'newcol' || strip(input(substr(varname,4),4.));
call execute('attrib ' || strip(nvarname) || ' length=$250;');
call execute(strip(nvarname) || '= "<a>" || strip(' || strip(varname) || ') || "</a>";' );
if lastrec then do;
call execute('drop oldcol1-oldcol1000;');
call execute('run;');
end;
run;