SQL или функция SAS для вменения категориальных переменных на основе других аналогичных записей - PullRequest
1 голос
/ 17 марта 2020

У меня есть набор данных, который похож на то, что я вставил ниже. Что мне нужно сделать, это заполнить все пропущенные значения в столбце группы на основе значений в столбце group_no. Например, если Group_no равен 1, тогда все значения для Group должны быть «Crops».

Я попробовал несколько вещей, совсем недавно оператор CASE WHEN, который, как я думал, сработал, но провалился. Я пробовал if / else, но есть 200 тыс. Записей и 8000 различных групп, и я не уверен, как go об этом, не обновляя каждую запись по одной. Некоторое время я крутил свои колеса с этим, и я думаю, что набор глаз * fre sh мог бы помочь.

Когда я запускаю код ниже, я получаю ошибку

ОШИБКА: подзапрос оценивается более чем в одну строку.

Я делаю это в SAS, используя Pro c SQL, поэтому, если у вас есть более простой подход с использованием шаг данных, тогда это тоже приветствуется.

proc sql;
select 
a.ID
, a.Group
, a.Industry
, a.Group_no
,CASE WHEN a.Group IN (' ') THEN (select first(b.group) from mydata as b where first(a.Group_no) = first(b.Group_no)) END AS group_desc2
from mydata as a;
quit;

enter image description here

Ответы [ 2 ]

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

SQL

Коррелированный подзапрос вызывает ERROR:, так как он имеет несколько строк:

, CASE 
    WHEN a.Group IN (' ') 
    THEN (select first(b.group) from mydata as b where first(a.Group_no) = first(b.Group_no)) 
  END AS group_desc2

Измените подзапрос на один это возвращает одну строку. Что-то вроде:

, case 
    when not missing(group) then group
    else (select min(group) from have as inner where inner.group_no = outer.group_no)
  end
  as group

Важные напоминания SAS SQL:

  • Пропущенные значения считаются значением NULL.
  • Агрегатные функции работают только с ненулевыми значениями.
  • Пустой коррелированный подзапрос (т. Е. Без строк) приводится к нулевому значению при назначении во внешнюю область.

Сведения о данных

  • Для @Reeza может быть лучше использовать стандартные таблицы поиска, а не значения поиска «самостоятельно найденные».
  • Что касается найденных самостоятельно,
    • Что должно произойти когда значение group отсутствует в всех строках группы GROUP_NO?
    • Что должно произойти, если у 'группы' есть несколько значений с группой GROUP_NO?

ДАННЫЕ Шаг

Per @ Stu-Sztukowski

  • путь # 1 не будет отображаться сделайте что-нибудь, если при first.group_no значение group отсутствует (т. е. ' ').
  • путь # 2 может вызвать ERROR: This range is repeated..., когда в group_no происходит несколько значений group.

ДАННЫЕ Шаг - Путь № 3

Используйте DOW l oop для захвата первого не пропущенного значения group и последующего серийного l oop применять по мере необходимости. * 1 066 *


data want(drop=_:);
  length _first_group $20.;

  * data is pre-sorted by `group_no`;
  do _n_ = 1 by 1 until (last.group_no);
    set have;
    by group_no;
    if missing(_first_group) then
      _first_group = group;
  end;

  do _n_ = 1 to _n_;
    set have;
    if missing (group) then group=_first_group;
    output;
  end;
run;
2 голосов
/ 17 марта 2020

Два способа:

Способ 1.

Сортировка по group_no descending group и заполнение пропущенных значений правильным значением группы.

Для каждого номера группы сохраните имя группы во временной создаваемой нами переменной с именем _group, которая переносится до следующего номера группы. _group всегда будет содержать имя текущего номера группы и позволит вам заполнить его по мере необходимости. Поскольку мы отсортировали набор данных по descending group, действительное имя группы всегда будет первым наблюдением в номере группы (если они все отсутствуют).

proc sort data=have;
    by group_no descending group;
run;

data want;
    set have;
    by group_no descending group;
    retain _group;

    if(first.group_no) then group = _group;

    if(missing(group)) then group = _group;

    drop _group;
run;

Способ 2.

Создать формат всех не пропущенных номеров групп / названий групп

При этом будет использоваться формат, чтобы связать номер группы с именем группы. Вы можете использовать SQL, чтобы создать набор данных формата специально для чтения в proc format. Оператор SQL, приведенный ниже, выбирает все отдельные номера пропущенных групп и предоставляет формат данных набора пропущенных номеров групп и названий групп. Используется для создания пользовательского формата с именем $groupfmt.. Эффективно действует как справочная таблица.

proc sql noprint;
    create table group_fmt as
        select distinct 
            group_no   as start
          , group_no   as end
          , group      as label
          , 'C'        as type
          , 'groupfmt' as fmtname
        from have
        where NOT missing(group)
        ;
quit;

proc format cntlin=group_fmt;
run;

data want;
    set have;

    if(missing(group)) then group = put(group_no, $groupfmt.);
run;

put(group_no, $groupfmt.) также может использоваться в запросе SQL вместо шага данных.

...