Как создать отдельные бары в порядке убывания в 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;
Другие вопросы по тегам