Создать идентификатор группы при группировке по нескольким переменным - PullRequest
0 голосов
/ 31 марта 2020

Я хотел бы создать переменную id для идентификации уникальных групп по нескольким переменным.

Например, у меня есть машины данных из sashelp.cars, и я хотел бы идентифицировать уникальные группы Make - DriveTrain и Cylinder с переменной id grp_id. Таким образом, тот же Make и тот же DriveTrain с другим номером Cylinder будут рассматриваться как новая группа (и, следовательно, новое значение в переменной id grp_id).

Я попытался сделать следующее, но при этом в случае нового случая будет сброшена переменная id, равная 1, и при этом не будет приниматься во внимание каждая уникальная комбинация Make + DriveTrain + Cylinder в качестве другого идентификатора группы.

data cars; set sashelp.cars; run;

proc sort data=cars; by Make DriveTrain Cylinders; run;
data cars; set cars; 
grp_id + 1;
by Make DriveTrain Cylinders
if first.Make or first.DriverTrain or first.Cylinders then grp_id = 1; 
run;

Есть идеи, как создать эту переменную grp_id, используя несколько переменных в качестве критерия?

Ответы [ 3 ]

3 голосов
/ 31 марта 2020

Вы хотите, чтобы каждая комбинация имела уникальный идентификатор группы. Не сбрасывайте идентификатор группы. Если бы вы также присваивали порядковый номер в группе, вы бы сбросили переменную последовательности.

Когда необходимо выполнить сброс. Для комбинаций увеличивайте идентификатор группы, когда последний из перечисленных переменных помечен как имеющий состояние first.

Пример:

proc sort data=sashelp.cars out=cars; 
  by Make DriveTrain Cylinders;
run;

data cars;
  set cars;
  by Make DriveTrain Cylinders;

  if first.Cylinders then grp_id + 1;

  * this answer gives you bonus information ! ;
  if first.Cylinders 
    then seq_in_group = 1; 
    else seq_in_group + 1;
run;

Примечание: Концептуально BY определяет иерархию из n переменных , Когда переменная в иерархии изменяет значение, во время последовательного прохождения данных ее состояние устанавливается первым . var m = 1 . Кроме того, все подчиненные уровни first. automati c переменные будут иметь одинаковое состояние. Другими словами, это утверждение верно: first. var m + 1 = 1 ... first. var п = 1 .

2 голосов
/ 31 марта 2020

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

data cars;
   if _N_ = 1 then do;
      declare hash h ();
      h.definekey ('Make', 'DriveTrain', 'Cylinders');
      h.definedata ('grp_id');
      h.definedone();
   end;

   set sashelp.cars;

   if h.find () ne 0 then grp_id + 1;
   h.replace();
run;
1 голос
/ 31 марта 2020

Используя свой собственный код, вам нужно только сделать небольшое изменение

data cars; 
   set sashelp.cars; 
run;

proc sort data=cars; 
   by Make DriveTrain Cylinders; 
run;

data cars;
   set cars;
   by Make DriveTrain Cylinders;
   if first.Make or first.DriveTrain or first.Cylinders then grp_id + 1; 
run;
...