Как обнаружить все пустые столбцы в наборе данных и удалить \ удалить их? - PullRequest
4 голосов
/ 30 марта 2011

Как предлагается в заголовке, я бы хотел отбросить все пустые столбцы \ переменные (где все записи пустые или равны нулю или ""), чтобы уменьшить затраты времени при последующем выполнении.

Детальный сценарий:

У меня есть набор данных () с 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

ColNumber

 1

 2

 3

...

1000

Таким образом, вы можете представить, сколько раз будет выполняться поиск, поиск и установка значений.

Следовательно, я мог бы подумать о том, чтобы сократить затраты времени - сначала убрать все пустые столбцы. Но любые входные данные, касающиеся оптимизации алгоритма, также приветствуются.

Спасибо

Ответы [ 3 ]

2 голосов
/ 30 марта 2011

Вот универсальный макрос, который можно использовать для создания списка пустых столбцов в исходном наборе данных, который затем можно передать в оператор отбрасывания. Он использует формат 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 голос
/ 22 октября 2013

Я согласен, что proc transpose - хорошая идея:

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;
0 голосов
/ 30 марта 2011

Как то так?

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...