#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).