2

我目前正在尝试在 SAS 中使用 PROC SGPLOT 创建一个具有五行(8 年级、10 年级、12 年级、大学生和年轻人)的系列情节。y 轴是药物使用流行率的百分比,范围为 0-100。xaxis 是 1975-2019 年,但已格式化(使用 proc 格式),因此它将年份的值显示为 '75-'19。我想使用其各自的组(8 年级 - 年轻人)标记每条线。但是当我使用:

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 ;

系列情节在此处输入图像描述

“curvelabelpos=”没有提供将我的标签放在“12 年级”和“大学生”的第一个数据点上方的选项,这样我的 xaxis 就没有图左侧的所有空间。如何将这两个标签移动到每行的第一个数据点上方,以使 xaxis 没有空白空间?

4

2 回答 2

2

没有series可以产生您想要的标签的语句选项。

您必须为sgplot.

在此示例代码中,该curvelabel=选项被设置为,''因此该过程会生成一个使用最大水平绘图空间的系列线。该sganno数据集包含注释函数,这些函数将使用空白曲线标签在系列的第一个数据点附近绘制您自己的曲线标签文本。根据需要调整%sgtext anchor=值。请务必阅读SG Annotation Macro Dictionary文档以了解所有文本注释功能。

对于想要在系列行中进行人为拆分的情况,可以尝试两件事:

  • 引入一个假年份,2012.5,其中没有一个系列变量有值。我试过这个,但 5 个系列中只有 1 个是用“假”分割画的。
  • 为需要拆分的 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;

在此处输入图像描述

于 2020-01-30T06:16:10.833 回答
0

理查德回答了你明确想要的,但我认为你想要的从图形的角度来看并不理想——这就是为什么 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 ;

图表示例

于 2020-01-31T03:27:11.877 回答