слияние один-ко-многим в SAS (с несовпадающими записями) - PullRequest
0 голосов
/ 21 мая 2018

Я пытаюсь выполнить слияние в SAS, которое кажется легким, но до сих пор не найдено ничего, что указывало бы на то, как это сделать.У меня есть два набора данных - назовем их Monthly1 и Quarterly2.Monthly1 является основным, и я хочу включить Quarterly2 в него.Проблема в том, что последняя имеет другую периодичность, как следует из названия.Вот как выглядит каждый из них:

ЕЖЕМЕСЯЧНО1:

id,month,year,qname,data1,data2,data3,data4

1111,01,2018,First Quarter 2018,27,33,55
1111,02,2018,First Quarter 2018,28,34,54
1111,03,2018,First Quarter 2018,28,37,51
1111,04,2018,Second Quarter 2018,28,30,59
1112,01,2018,First Quarter 2018,1,7,12
1112,02,2018,First Quarter 2018,2,7,10
1112,03,2018,First Quarter 2018,5,6,7
1112,04,2018,Second Quarter 2018,4,1,8

КВАРТАЛЬНО2:

id,qname,data4,data5

1111,First Quarter 2018,53,7
1111,Second Quarter 2018,58,9
1112,First Quarter 2018,7,7
1112,Second Quarter 2018,7,9

Объединение id и qname.Таким образом, для каждого month в ЕЖЕМЕСЯЧНО1, data 4 перезаписывается с использованием значения в QUARTERLY2, а data 5 добавляется в качестве новой переменной.Окончательный набор данных должен выглядеть следующим образом (я добавил *, где данные из QUARTERLY2 либо добавлены, либо перезаписаны):

MERGED3:

id,month,year,qname,data1,data2,data3,data4,data5

1111,01,2018,First Quarter 2018,27,33,53*,7*
1111,02,2018,First Quarter 2018,28,34,53*,7*
1111,03,2018,First Quarter 2018,28,37,53*,7*
1111,04,2018,Second Quarter 2018,28,30,58*,9*
1112,01,2018,First Quarter 2018,1,7,7*,7*
1112,02,2018,First Quarter 2018,2,7,7*,7*
1112,03,2018,First Quarter 2018,5,6,7*,7*
1112,04,2018,Second Quarter 2018,4,1,7*,9*

Спасибо!

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Поскольку SAS будет перезаписывать столбцы с одинаковыми именами в merge, но только для первых совпадений, рассмотрите возможность переименования во время объединения.Затем оставьте нужные вам столбцы.Также ниже демонстрируется объединение влево (все строки в Montlhy1 независимо от того, совпадает ли оно с Quarterly1 ):

proc sort data=Monthly1; by id qname; run;
proc sort data=Quarterly2; by id qname; run;

data merged3;
    merge Monthly1(in=x RENAME=(data4=data4_x)) Quarterly2(in=y);
    by id qname;
    if x;
    keep id month year qname data1-data5; 
run;

В качестве альтернативы рассмотрим объединение влевообъединитесь с proc sql и явно сохраните столбцы, которые вы намерены обозначать псевдонимами таблиц.Опять же, left join используется:

proc sql;
    create table merged4 as
    select m.id, m.month, m.year, m.qname, m.data1, m.data2, m.data3, q.data4, q.data5
    from Monthly1 m
    left join Quarterly2 q
      on m.id = q.id AND m.qname = q.qname;
quit;
0 голосов
/ 21 мая 2018

Замечание по использованию 48705 : Слияние «один ко многим» с общими переменными, которые не являются переменными BY, будет иметь значения из множества данных после первого наблюдения, состояния:

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

Вы можете изменить поведение, переименовав переменную non-by, чтобы она не была общей - новаянестандартное значение переменной будет поддерживаться во всех последующих сопоставлениях и может применяться.

Например (ваши данные)

Ежемесячно (множество)

data have_monthly;
infile cards dlm=',';
length id month year 8 qname $30; input
id month year qname data1 data2 data3; data4=_n_*1000; datalines;
1111,01,2018,First Quarter 2018,27,33,55
1111,02,2018,First Quarter 2018,28,34,54
1111,03,2018,First Quarter 2018,28,37,51
1111,04,2018,Second Quarter 2018,28,30,59
1112,01,2018,First Quarter 2018,1,7,12
1112,02,2018,First Quarter 2018,2,7,10
1112,03,2018,First Quarter 2018,5,6,7
1112,04,2018,Second Quarter 2018,4,1,8
run;

Ежеквартально (один)

data have_quarterly;
infile cards dlm=',';
length id 8 qname $30;
input id qname data4 data5; datalines;
1111,First Quarter 2018,53,7
1111,Second Quarter 2018,58,9
1112,First Quarter 2018,7,7
1112,Second Quarter 2018,7,9
run;

Слияние по умолчанию

data try (label="The quarter data4 values are not propagated");
  merge
    have_monthly
    have_quarterly
  ;
  by
    id
    qname
  ;
run;

То же слияние с переименованием, чтобы обеспечить нестандартность в переменной non-by data4

data want(label="The quarter data4 values are propagated");
  merge
    have_monthly
    have_quarterly (rename=data4=_data4)
  ;
  by
    id
    qname
  ;
  data4 = _data4;
run;
...