Как мне удалить несколько переменных столбца в SAS, которые просто указывают «Null», но не являются пустыми? - PullRequest
0 голосов
/ 20 сентября 2018

Как мне удалить несколько переменных столбца в SAS, которые просто указывают «Null», но не являются пустыми?Я создал следующую таблицу:

DATA test;
INPUT name$ favourite_food$ occupation$ favourite_sport$;
CARDS;
John Null Nurse Null 
Michelle Null Lawyer Null
Peter Null Teacher Null 
Kai Null Doctor Null 
run;

Поскольку столбцы со значениями Null не являются пустыми, я не уверен, как удалить эти столбцы.Они мне не нужны для моего анализа.

Также я знаю, что могу использовать команду drop для удаления столбцов.Однако, когда у меня есть около 90 переменных, есть более эффективный способ отбросить несколько «нулевых» переменных

Ответы [ 4 ]

0 голосов
/ 20 сентября 2018

У вас есть два варианта для этого случая.

1-й, используйте удержание.Функция keep хранит нужную вам переменную, поэтому, если вы уже знаете, какие переменные отличны от NULL, просто поместите в keep, например:

DATA test (keep = любимое_полное питание);

INPUT name$ favourite_food$ occupation$ favourite_sport$;
CARDS;
John Null Nurse Null 
Michelle Null Lawyer Null
Peter Null Teacher Null 
Kai Null Doctor Null 

run;

Если вы знаете, чтоavor_food и занятие не NULL.

2nd, используйте пример функции удаления:

DATA test;

INPUT name$ favourite_food$ occupation$ favourite_sport$;
CARDS;
   if name eq NULL then delete;

Бег;

Удачи!

0 голосов
/ 20 сентября 2018

Параметр nlevels в proc freq возвращает количество различных значений в каждом столбце.Поэтому любые столбцы, в которых все значения одинаковы, будут иметь значение уровня nlevel 1.

Если вы уверены, что это правило будет применяться только к столбцам «Null», то вы можете использовать этот метод (т. Е.минимум 2 различных значения имени, рода занятий и т. д.)

Значение nlevel не включается автоматически в выходную таблицу в пределах proc freq, поэтому вам нужно использовать ods output, чтобы получить имена столбцов вТаблица.Затем вы можете назначить их макропеременной, которая будет использоваться в операторе drop в любой процедуре анализа, которую вы используете.Или вы можете удалить их, как вы просили, в шаге данных.(Я обычно предпочитаю первый вариант, на случай, если действительные данные будут удалены ошибочно).

DATA test;
INPUT name$ favourite_food$ occupation$ favourite_sport$;
CARDS;
John Null Nurse Null 
Michelle Null Lawyer Null
Peter Null Teacher Null 
Kai Null Doctor Null 
run;

/* identify columns with only 1 distinct value and output to a table */
ods output nlevels = distinct_values (where=(nlevels=1));
proc freq data=test nlevels;
run;

/* store column names in macro variable */
proc sql noprint;
select tablevar into :drop_cols separated by ' '
from distinct_values;
quit;

%put &drop_cols;

/* exclude columns from analysis */
proc freq data=test (drop=&drop_cols.);
run;
0 голосов
/ 20 сентября 2018

Просто еще один способ сделать это с помощью sql в макросе.Подробные комментарии добавлены.Решение @longfish простое и очень эффективное.

   %macro abc;
/* picking up the variables on which Null check is needed*/
   proc sql;
    /*finding total number of obervations*/
      select count(*) into :cnt from test;
       select name into :name separated by '|' from dictionary.columns
            where upcase(memname) = 'TEST'
            and lowcase(name) like '%favourite_%';

    /*creting temporary table to hold the values which should be dropped*/
    create table temptable(col char(50),val num);;

    /* looping through variables for which null check is needed*/
    %do i = 1 %to %sysfunc(countw(&name, |));
        %let col_val =%scan(&name,&i,|);

        /* total obervations minus count for variables with null values gives 0
        indicates that all are null values and are inseted in a temptable*/
proc sql;
    insert into temptable
        select col, val from
        (select "&col_val" as col , &cnt- count(&col_val) as val
            from test
                where &col_val = "Null")
                where val = 0;
    %end;

    /*picking up all the columns to be dropped*/
proc sql;
    select col into  :drop_columns separated by ' '
        from temptable;
    %put &drop_columns;

    /* dropping the columns*/
data want;
    set test(drop=&drop_columns);
run;

%mend;

%abc;
0 голосов
/ 20 сентября 2018

Требуется полное сканирование данных, чтобы проверить все значения во всех столбцах.Во время сканирования появление значения, отличного от "Null", исключит этот столбец в качестве кандидата на удаление.

Вы можете использовать временный массив для отслеживания имен столбцов символов, а другой массив установить на _CHARACTER_, чтобы эти столбцы можно было перебирать в каждой строке.Процесс создаст список столбцов, которые можно отбросить в соответствии с вашими критериями - этот список помещается в таблицу символов макросов и может использоваться в последующем коде, чтобы либо перезаписать данные без этих столбцов, либо просто удалитьих во время обработки с использованием опции набора данных.

DATA test;
INPUT name$ favourite_food$ occupation$ favourite_sport$;
CARDS;
John Null Nurse Null 
Michelle Null Lawyer Null
Peter Null Teacher Null 
Kai Null Doctor Null 
Zonker Null Null Null
run;

%let DROP_VARS=;

data _null_;
  set test end=end;

  array char_vars _CHARACTER_;               * for iterating over values;
  array null_vars (1000) $32 _temporary_ ;   * for tracking column names;

  * populate column name tracking array;
  if _n_ = 1 then do;
    do index = 1 to dim(char_vars);
      null_vars(index) = vname(char_vars(index));
    end;
  end;

  * scan each row, iterating over character variables;
  * remove a column name from drop consideration when non "Null" occurs;
  do index = 1 to dim(char_vars);
    if not missing(null_vars(index)) then
      if char_vars(index) ne "Null" then
        null_vars(index) = '';
  end;

  * place space separated list of columns containing only "Null" in macro symbol table;
  if end then
    call symput('DROP_VARS', catx(' ', of null_vars(*)));
run;

* use macro variable as desired;

%put NOTE: &=DROP_VARS;

proc print data=test(drop=&DROP_VARS);
  title "Non-null columns of TEST";
run;

data TEST2(label="Copy of Test, excluding null columns");
  set TEST;
  drop &DROP_VARS;
run;

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

...