SAS: заменить редкие уровни в переменной на новый уровень «Другое»

#sas

#sas

Вопрос:

У меня есть довольно большая таблица, в которой я хочу заменить редкие значения (для этого примера, которые имеют менее 10 вхождений, но реальный случай сложнее — он может иметь 1000 уровней, в то время как я хочу иметь только 15). Этот список возможных уровней может измениться, поэтому я не хочу ничего жестко кодировать.

Мой код похож:

 %let var = Make;

    proc sql;

    create table stage1_ as
        select amp;var.,
               count(*) as count
        from sashelp.cars
        group by amp;var.
        having count >= 10 
        order by count desc

    ;
    quit;

    /* Join table with table including only top obs to replace rare
       values with "other" category */
    proc sql;
    create table stage2_ as 
        select t1.*,
                case when t2.amp;var. is missing then "Other_amp;var." else t1.amp;var. end as amp;var._new
        from sashelp.cars t1 left join 
             stage1_ t2 on t1.amp;var. = t2.amp;var.
    ;
    quit;

    /* Drop old variable and rename the new as old */
    data resu<
        set stage2_(drop= amp;var.);
        rename amp;var._new=amp;var.;
    run;
 

Это работает, но, к сожалению, это не очень удобно, так как для каждой переменной требуется объединение (в реальном случае я делаю это в цикле).
Есть ли лучший способ сделать это? Может быть, какая-нибудь умная функция замены?

Спасибо!!

Комментарии:

1. Для случая символьной переменной, скажем pqr , сопоставляемой pqr_new , значение, не являющееся 10 наиболее частым (ваше определение редкого ) pqr , будет изменено на литерал "Other_pqr" . В случае числовой переменной, скажем xyz , сопоставляемой с xyz_new , какое буквальное значение будет использоваться для указания отличия для ее редких числовых значений?

2. Количество уровней на самом деле не проблема, беспорядок будет больше из-за количества переменных. Со сколькими переменными вы имеете дело? Вы хотите автоматически сопоставить все переменные или только те, которые вы укажете?

Ответ №1:

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

FREQ Процедура ODS может использоваться для записи количества и процентов каждой переменной, перечисленных в одной таблице. ПРИМЕЧАНИЕ: Freq table/out= фиксируется только последняя переменная в списке. Эти значения могут быть использованы для построения формата в соответствии с правилами «othering», которые вы хотите реализовать.

 data have;
  do row = 1 to 1000;
    array x x1-x10;
    do over x;
      if row < 600 
        then x = ceil(100*ranuni(123));
        else x = ceil(150*ranuni(123));
    end;
    output;
  end;
run;

ods output onewayfreqs=counts;

proc freq data=have ;
  table x1-x10;
run;

data count_stack;
  length name $32;
  set counts;
  array x x1-x10;
  do over x;
    name = vname(x);
    value = x;
    if value then output;
  end;
  keep name value frequency;
run;

proc sort data=count_stack;
  by name descending frequency ;
run;

data cntlin;
  do _n_ = 1 by 1 until (last.name);
    set count_stack;
    by name;
    length fmtname $32;
    fmtname = trim(name)||'top';
    start = value;
    label = cats(value);
    if _n_ < 11 then output;
  end;
  hlo = 'O';
  label = 'Other';
  output;
run;

proc format cntlin=cntlin;
run;

ods html;

proc freq data=have;
  table x1-x10;
  format
    x1 x1top.
    x2 x2top.
    x3 x3top.
    x4 x4top.
    x5 x5top.
    x6 x6top.
    x7 x7top.
    x8 x8top.
    x9 x9top.
    x10 x10top.
  ;
run; 
 

Комментарии:

1. Я принял этот ответ, потому что мне не было ясно его назначение. Предполагалось, что он был изменен навсегда, поскольку данные позже использовались для целей моделирования (в другой среде — python).