Проблема SAS с кривыми метками и осями в PRO C SGPLOT - PullRequest
2 голосов
/ 29 января 2020

В настоящее время я пытаюсь использовать PRO C SGPLOT в SAS для создания сериала из пяти линий (8-й класс, 10-й класс, 12-й класс, студенты колледжа и молодые взрослые). Yaxis - это процент распространенности употребления наркотиков в диапазоне от 0 до 100. Xaxis - это год 1975-2019, но отформатированный (с использованием формата pro c), поэтому он показывает значение года как '75 -'19. Я хотел бы обозначить каждую строку, используя соответствующую группу (8-й класс - Young Adult). Но когда я использую:

proc sgplot data = save.fig2_1data noautolegend ;
series x=year y=eighth / lineattrs=(color=orange) curvelabel='8th Grade' curvelabelpos=start ;
series x=year y=tenth / lineattrs=(color=green) curvelabel='10th Grade' curvelabelpos=start ;
series x=year y=twelfth / lineattrs=(color=blue) curvelabel='12th Grade' curvelabelpos=start;
series x=year y=college / lineattrs=(color=red) curvelabel='College Students' curvelabelpos=start;
series x=year y=youngadult / lineattrs=(color=purple) curvelabel='Young Adults' curvelabelpos=start ;
xaxis label="YEAR" values=(1975 to 2019 by 2) minor;
yaxis label="PERCENT" max=100 min=0 ;
format year yr. ; run ;

Сюжет серии enter image description here

"curvelabelpos =" не дает возможности разместить мой Пометьте над первой точкой данных «12-й класс» и «Студенты колледжа», чтобы у моей оси не было всего пространства с левой стороны графика. Как мне переместить эти две метки над первой точкой данных каждой строки, чтобы на оси не было пустого пространства?

Ответы [ 2 ]

2 голосов
/ 30 января 2020

Нет параметров оператора series, которые будут производить желаемую маркировку.

Вам нужно будет создать набор данных аннотации для sgplot.

В этом примере кода параметр curvelabel= был установлен на '', поэтому процедура генерирует линию серии, которая использует самый большой объем горизонтального пространства рисования. Набор данных sganno содержит функции аннотации, которые будут рисовать ваш собственный текст метки кривой рядом с первой точкой данных ряда с пустой меткой кривой. Отрегулируйте значение %sgtext anchor= по мере необходимости. Обязательно ознакомьтесь с документацией SG Annotation Macro Dictionary , чтобы понять все возможности текстовой аннотации.

В случае необходимости искусственного разделения в строках серии есть две вещи, которые нужно попробовать:

  • вводит фиктивный год 2012.5, для которого ни одна из переменных серии не имеет значения. Я пробовал это, но только 1 из 5 дро с «поддельным» разделением.
  • вводит N новых переменных для N линий, нуждающихся в разделении. Для периода времени после разделения скопируйте данные в новые переменные и установите для оригинала значение отсутствующее.
    • добавить SERIES операторов для новых переменных.
data have;
  call streaminit(1234);

  do year = 1975 to 2019;
    array response eighth tenth twelfth college youngadult;

    if year >= 1991 then do;
      eighth = round (10 + rand('uniform',10), .1);
      tenth = eighth + round (5 + rand('uniform',5), .1);
      twelfth = tenth + round (5 + rand('uniform',5), .1);

      if year in (1998:2001) then tenth = .;
    end;
    else do;
      twelfth = 20 + round (10 + rand('uniform',25), .1);
    end;

    if year >= 1985 then do;
      youngadult = 25 + round (5 + rand('uniform',20), .1);
    end;

    if year >= 1980 then do;
      college = 35 + round (7 + rand('uniform',25), .1);
    end;

    if year >= 2013 then do _n_ = 1 to dim(response);
      %* simulate inflated response level;
      if response[_n_] then response[_n_] = 1.35 * response[_n_];
    end;

    output;
  end;
run;

data have_split;
  set have;
  array response  eighth  tenth  twelfth  college  youngadult;
  array response2 eighth2 tenth2 twelfth2 college2 youngadult2;

  if year >= 2013 then do _n_ = 1 to dim(response);
    response2[_n_] = response[_n_];
    response [_n_] = .;
  end;
run;

ods graphics on;
ods html;

%sganno;

data sganno;
  %* these variables are used to track '1st' or 'start' point 
  %* of series being annotated
  ;
  retain y12 ycl;

  set have;
  if missing(y12) and not missing(twelfth)  then do; 
    y12=twelfth;
    %sgtext(label="12th Grade", textcolor="blue", drawspace="datavalue", anchor="top", x1=year, y1=y12, width=100, widthunit='pixel')
  end;     

  if missing(ycl) and not missing(college) then do; 
    ycl=college; 
    %sgtext(label="College Students", textcolor="red", drawspace="datavalue", anchor="bottom", x1=year, y1=ycl, width=100, widthunit='pixel')
  end;
run;


proc sgplot data=have_split noautolegend sganno=sganno;
series x=year y=eighth     / lineattrs=(color=orange) curvelabel='8th Grade'        curvelabelpos=start;*auto curvelabelloc=outside ;
series x=year y=tenth      / lineattrs=(color=green)  curvelabel='10th Grade'       curvelabelpos=start;*auto curvelabelloc=outside ;
series x=year y=twelfth    / lineattrs=(color=blue)   curvelabel='' curvelabelpos=start;*auto curvelabelloc=outside ;
series x=year y=college    / lineattrs=(color=red)    curvelabel='' curvelabelpos=start;*auto curvelabelloc=outside ;
series x=year y=youngadult / lineattrs=(color=purple) curvelabel='Young Adults'     curvelabelpos=start;*auto curvelabelloc=outside ;

* series for the 'shifted' time period use the new variables;
series x=year y=eighth2     / lineattrs=(color=orange) ;
series x=year y=tenth2      / lineattrs=(color=green)  ;
series x=year y=twelfth2    / lineattrs=(color=blue)   ;
series x=year y=college2    / lineattrs=(color=red)    ;
series x=year y=youngadult2 / lineattrs=(color=purple) ;

xaxis label="YEAR" values=(1975 to 2019 by 2) minor;
yaxis label="PERCENT" max=100 min=0 ;
run ;

ods html close;
ods html;

enter image description here

0 голосов
/ 31 января 2020

Ричард ответил, что вы явно хотите, но я думаю, что вы хотите, не является идеальным с графической точки зрения - и именно поэтому SAS не сделает это за вас.

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

В этом случае я бы использовал CURVELABELLOC = OUTSIDE и либо использовал CURVELABELPOS = MAX (по умолчанию, который размещает их справа от диаграммы), либо CURVELABELPOS = MIN, что ставит их ближе к началу, как вы предпочитаю, но также накладываю ось (которая не так чиста).

Посмотрите это в качестве примера. Это легко читается, метки кривых находятся в месте, куда глаз естественным образом перемещается, и не изменяют размер оси. Размещение их справа также означает, что они находятся в одном месте для всех линий, что чище, чем располагать их в начале линий в шахматном порядке.

data fig2_1data;
  call streaminit(7);
  tenth  = 0.5;
  twelfth= 0.6;
  do year=1975 to 2019;
    if year eq 1987 then eighth=0.4;
    eighth = rand('Uniform',0.2)-0.1 + eighth;
    tenth = rand('Uniform',0.2)-0.1 + tenth;
    twelfth = rand('Uniform',0.2)-0.1 + twelfth;
    output;
 end;
run;
proc sgplot data = fig2_1data noautolegend ;
series x=year y=eighth / lineattrs=(color=orange) 
                         curvelabel='8th Grade' curvelabelpos=max curvelabelloc=outside;
series x=year y=tenth / lineattrs=(color=green) 
                        curvelabel='10th Grade' curvelabelpos=max curvelabelloc=outside;
series x=year y=twelfth / lineattrs=(color=blue) 
                        curvelabel='12th Grade' curvelabelpos=max curvelabelloc=outside;
xaxis label="YEAR" values=(1975 to 2019 by 2) minor;
yaxis label="PERCENT" max=1 min=0 ;
format year yr. ; run ;

Chart example

...