如何检测数据集中的所有空列并删除\删除它们?

时间:2011-03-30 06:32:06

标签: sql sas

正如标题中所建议的那样,我想删除所有空列\变量(其中所有记录都为空或等于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;

由于以下原因,执行需要相当长的时间:

  1. 旧列的数量巨大

  2. 实际上我需要在另一个数据集中做一个循环来设置 oldcol

  3. 之后的数字

    ColNumber

     1
    
     2
    
     3
    

    ...

    1000

    因此,您可以想象在搜索,查找和设置值方面要执行多少次。

    因此,我认为减少时间成本的一种方法是首先删除所有空列。但是,关于优化算法的任何输入也都受到欢迎。

    由于

3 个答案:

答案 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 &noteopt.;
%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;