Если ваши данные имеют значение категории в виде вкрапленной строки, вам необходимо создать третий столбец для хранения этих значений при обнаружении при прохождении набора данных.Для обсуждения назовите этот новый столбец group
- он также будет категоричным и иерархически «выше» другого столбца категории.Это «синтетическая» категория, которая необходима для выполнения сложного объединения и будет исключена из окончательного результата.
Объединение want
будет простым «черным ящиком», включающим группировку, объединение, скрытую математикуи групповая сумма суммы строк.
В примере кода создается таблица fulljoin_peek
, которая не нужна для результатов, но позволит получить представление о данных, проходящих через черный ящик.Код также обрабатывает случай «данных реального мира» для категории, повторяющейся в группе.
Пример данных:
data testA;
input categorical $3. value;
datalines;
Dog . * missing means categorical is really group
M 7
F 5
Cat .
M 4
F 2
Rat . * B does not have rat
T 5
Bat . * Bat has two M (repeated category) need to be summed
M 7
M 3
Fly .
M 5
F 6
;
run;
data testB;
input categorical $3. value;
datalines;
Dog . * only one category
F 3
Cat .
M 1
F 2
Cow . * A does not have cow
X 7
Bat . * Bat has two F (repeated category) need to be summed
F 7
F 13
Fly . * F M order different than A
F 16
M 20
;
run;
Расширенные данные имеют столбец группы и информацию об исходном порядке:
data A2;
set testA;
if value = . then do;
* presume missing is the 'discovery' of when the
* group value has to be assigned;
group = categorical; retain group;
group_order + 1;
value_order = 0;
end;
value_order + 1;
format group_order value_order 4.;
run;
data B2;
set testB;
if value = . then do;
* presume missing is the 'discovery' of when the
* group value has to be assigned;
group = categorical; retain group;
group_order + 1;
value_order = 0;
end;
value_order + 1;
format group_order value_order 4.;
run;
Операции соединения (просмотр данных)
* this full join shows how data matches up for the answer
* the answer will use grouping, coalescing, summing and adding;
proc sql;
create table fulljoin_peek as
select
coalesce (A.categorical, B.categorical) as want_categorical
, sum(A.value,B.value) as want_value format=4.
, A.group as A_group
, B.group as B_group
, A.group_order as A_group_order
, B.group_order as B_group_order
, A.categorical as A_cat
, B.categorical as B_cat
, A.value as A_value
, B.value as B_value
, A.value_order as A_value_order
, B.value_order as B_value_order
from
A2 as A
full join
B2 as B
on
A.group = B.group
and A.categorical = B.categorical
;
Требуется соединение (ответ)
proc sql;
create table
want (drop=group_order value_order) as
select
coalesce (A.categorical, B.categorical) as want_categorical
, min (coalesce (A.group_order-1e6,B.group_order)) as group_order
, min (coalesce (A.value_order-1e6,B.value_order)) as value_order %* -1e6 forces A order to have precedence ;
, sum ( sum (A.value,B.value) ) as value
from
A2 as A
full join
B2 as B
on
A.group = B.group
and A.categorical = B.categorical
group by
A.group, want_categorical
order by
group_order, value_order
;