как создать отдельные бары в порядке убывания в proc sgplot?

Я создал следующий график, используя sgplot

proc sgplot data=Colordistricts;
hbar distrct/response=Percent 
group= population;
run;  

введите здесь описание изображения

Однако кажется, что отдельные группы населения расположены на графике в алфавитном порядке (азиатские, за которыми следуют чернокожие и белые).

Как создать такой же график с группами населения в порядке убывания в процентах?

На самом деле это районы, где цветное население является самым высоким. В основном я хочу создать график, чтобы каждый столбец начинался с цветовой популяции.


person Nathan123    schedule 21.04.2018    source источник
comment
Попробуйте CategoryOrder или GROUPORDER? Какая у вас версия SAS, параметры различаются в зависимости от вашей версии.   -  person Reeza    schedule 22.04.2018
comment
Как следует расположить другие сегменты совокупности после размещения Color на первой позиции совокупности? Сортировка по определенному проценту может привести к беспорядку в элементе совокупности (цветные полосы в разных местах), а сортировка по элементу совокупности может привести к беспорядку в процентах (зубчатые столбцы одного цвета).   -  person Richard    schedule 22.04.2018
comment
@Reeza У меня SAS 9.4   -  person Nathan123    schedule 23.04.2018
comment
@Richard Я хочу, чтобы порядок был цветным, белым, черным и азиатским.   -  person Nathan123    schedule 23.04.2018
comment
@ Nathan123 Nathan123, вам нужно указать точную версию, то есть 9.4 TS1M5 или M4. Есть значительные улучшения после М3 и в М5.   -  person Reeza    schedule 23.04.2018
comment
@Reeza У меня 9.04.01M3P062415   -  person Nathan123    schedule 23.04.2018


Ответы (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;

Принудительный групповой порядок

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. Этот процесс потребует дополнительного кодирования для определения новых сопоставлений для других значений идентификатора населения. В этом дополнительном примере показано, как глобальная сумма ответов используется для упорядочения по убыванию оставшихся сегментов населения в районе.

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;
person Richard    schedule 22.04.2018