Как создать отдельные бары в порядке убывания в proc sgplot?
Я создал следующий график, используя sgplot
proc sgplot data=Colordistricts;
hbar distrct/response=Percent
group= population;
run;
Тем не менее, кажется, что отдельные группы населения расположены в алфавитном порядке на графике (азиатский, затем черный и белый цвета).
Как мне создать этот же участок с группами населения в порядке убывания в процентах?
На самом деле это районы, где цветовая популяция самая высокая. В основном я хочу создать график, чтобы каждая полоса начиналась с цветовой популяции
1 ответ
Чтобы принудительно указать конкретное значение группы в первой позиции, вы можете сопоставить желаемую группу с новым значением, которое будет сопоставляться первым. Иногда это легко сделать, поместив символ пробела перед существующим значением.
Если переменная группы представляет собой числовой идентификатор, отформатированный для отображения метки связанной группы, вы можете создать новую версию пользовательского формата, включив в нее идентификатор 0, соответствующий принудительной группе. Принудительная группа сопоставляется с 0 идентификатором.
Затем вы должны отсортировать данные нужным вам способом и использовать SGPLOT. yaxis type=discrete discreteOrder=data;
заставить категории hbar появляться в определенном порядке.
Вот пример кода для изучения. Окончательный SGPLOT использует технику картирования, чтобы заставить определенный сегмент населения появляться первым.
ods html close;
%let path = %sysfunc(pathname(work));
ods html file="&path.\sgplot_hbar.html" gpath="&path.";
proc format;
value popId
0 = 'Color'
1 = 'Asian'
2 = 'Black'
3 = 'Color'
4 = 'White'
;
data have;
do _n_ = rank('A') to rank('P');
district = byte (_n_);
x = 0;
populationID = 2; percent = ceil(40*ranuni(123)); output;
x + percent;
populationID = 3; percent = ceil(40*ranuni(123)); output;
x + percent;
if (ranuni(123) < 0.10) then do;
populationID = 1; percent = ceil(10*ranuni(123)); output;
x + percent;
end;
percent = 100 - x;
populationID = 4;
output;
end;
keep district populationID percent;
label
percent = 'Percent of Total Frequency'
;
format
populationID popId.
;
run;
proc sgplot data=have;
hbar district
/ group = populationID
response = percent
;
title j=L 'default group order by populationID value';
title2 j=L 'districts (yaxis) also implicitly sorted by formatted value';
run;
proc sgplot data=have;
hbar district
/ group = populationID
response = percent
categoryOrder = respAsc
;
title j=L 'categoryOrder: ascending response';
title2 j=L 'districts (yaxis) also implicitly sorted by min(response)';
run;
proc sgplot data=have;
hbar district
/ group = populationID
response = percent
categoryOrder = respDesc
;
title j=L 'categoryOrder: descending response';
title2 j=L 'districts (yaxis) also implicitly sorted by descending max(response)';
run;
proc sql;
create table have2 as
select
case
when populationID = 3 then 0 else populationID
end as hbar_populationID format=popId.
, *
from have
order by
hbar_populationID, percent
;
quit;
proc sgplot data=have2;
yaxis type=discrete discreteOrder=data;
hbar district
/ group = hbar_populationID
response = percent
;
title j=L 'population seqment ordering is partially forced by tweaking populationID values';
title2 j=L 'districts in data order per yaxis statement';
run;
Принудительный groupOrder
SQL может сортировать данные в определенном порядке, используя case
в order by
пункт. Вы бы тогда использовали groupOrder=data
в SGPLOT.
proc sql;
create table have3 as
select *
from have
order by
district
, case
when populationID = 3 then 0
when populationID = 2 then 1
when populationID = 4 then 2
when populationID = 1 then 3
else 99
end
;
quit;
proc sgplot data=have3;
hbar district
/ group = populationID
groupOrder = data
response = percent
;
title j=L 'population seqment ordering is partially forced by tweaking populationID values';
title2 j=L 'districts in data order per yaxis statement';
run;
Вынуждая один сегмент быть первым, а затем другие сегменты, полагаясь на значения ответа
После сопоставления идентификатора населения от 2 до 0 вы можете заставить упорядочить оставшиеся сегменты населения аналогично respAsc
или же respDesc
, Этот процесс потребует дополнительного кодирования для определения новых отображений для других значений popID. В этом дополнительном примере показано, как глобальная сумма ответов используется для наведения в порядке убывания оставшихся сегментов населения в пределах района.
proc sql;
create table way as
select populationID, sum(percent) as allPct
from have
where populationID ne 3
group by populationID
order by allPct descending
;
data waySeq;
set way;
seq + 1;
run;
proc sql;
create table have3 as
select
have.*
, case
when have.populationID = 3 then 1000 else 1000+seq
end as hbar_populationID
from have
left join waySeq on have.populationID = waySeq.populationID
order by
hbar_populationID, percent
;
create table fmtdata as
select distinct
hbar_populationID as start
, put(populationID, popId.) as label
, 'mappedPopId' as fmtname
from have3;
quit;
proc format cntlin = fmtdata;
run;
%let syslast = have3;
proc sgplot data=have3;
yaxis type=discrete discreteOrder=data;
hbar district
/ group = hbar_populationID
response = percent
groupOrder = data
;
format hbar_populationID mappedPopId.;
title j=L 'population seqment ordering is partially forced by tweaking populationID values';
title2 j=L 'districts in data order per yaxis statement';
run;
title;