SAS Proc GCHART相当于Proc GPLOT UNIFORM

时间:2013-12-05 22:23:33

标签: sas

有没有办法用proc gchart制作带有统一轴的多个条形图?

在proc gplot中,我可以像这样使用统一选项:

proc gplot data=test uniform;
  by state;
  plot var*date;
run;

这将为我提供一组所有使用相同轴范围的变量图。

此选项对于proc gchart不存在 - 有没有其他方法可以执行此操作?我不能只定义一个固定的范围,因为我的数据会有所不同。

1 个答案:

答案 0 :(得分:0)

感谢大家的投入。 由于看起来在proc本身内没有一个好的解决方案,我采用宏观方法来手动设置轴。

本文为我的所作所为提供了基础: http://analytics.ncsu.edu/sesug/2012/BB-09.pdf

由于我无法在任何地方找到该程序的文本,除了那些不可搜索的PDF,我在这里输入了它。我的版本添加了一个额外的参数,可选择填充低值,以便为低于低点的数据标签留出空间(如果您制作的柱状图表的标签高于正值且低于负值,则非常有用)

%macro set_axis_minmaxincrement(ds=,
                                axisvar=,
                                axis_length = 51,
                                sa_min = 999999,
                                sa_max = -999999,
                                returned_min = axis_min,
                                returned_max = axis_max,
                                returned_increment = axis_increment,
                                force_zero = 0,
                                pad_bottom = 0
                                ) ;

%global &returned_min &returned_max &returned_increment;

/* Find the high and low values. Note: a data step was used versus a proc */
/* to allow the application of the option parameters, if specified. */
proc sort data=&ds out=sortlb(keep=&axisvar);
  by &axisvar;
  where &axisvar ne .;
run;
data axisdata(keep=low high);
  retain low 0;
  set sortlb end=eof;
  by &axisvar;
  if _n_=1 then low = &axisvar;
  if eof then do;
    high = &axisvar;
    if &sa_min ^= 999999 and &sa_min < low then low = &sa_min;
    if &sa_max ^= -999999 and &sa_max > high then high = &sa_max;
    %if &force_zero = 1 %then %do;
      if low > 0 then low = 0;
      else if high < 0 then high = 0;
    %end;
    %if &pad_bottom = 1 %then %do;
      if low < 0 then low = low-((high-low)*.06);
    %end;
    output;
  end;
run;

data axisdata;
  set axisdata;
  /* insure that high is greater than low */
  if high <= low then do;
    if abs(low) <= 1 then high = low + 1;
    else high = low+10;
  end;

/* Calculate the conversion unit to transform the standard range to */
/* include the actual range. This value is used to convert the standard */
/* to the actual increment for the actual range. */

  axisrange = high - low;
/* ranges of less than 1 */
  if axisrange <= 6 then do;
    check = 6;
    conversion_unit = .01;
    do until (axisrange > check);
      check = check/10;
      if axisrange <= check then conversion_unit = conversion_unit / 10;
    end;
  end;

/* Ranges of 1 or greater */
  else do;
    check = 60;
    conversion_unit = 1.0;
    do while (axisrange > check);
      check = check*10;
      conversion_unit = conversion_unit * 10;
    end;
  end;
/* standardize the range to lie between 6 to 60 */
    unit_range = axisrange/conversion_unit;
/* Set the increment based on the unitized range */
/* 'Long' axis, 8 - 12 increments */
    %if &axis_length >50 %then %do;
      if      unit_range < 12 then axisinc = 1   * conversion_unit;
      else if unit_range < 24 then axisinc = 2   * conversion_unit;
      else if unit_range < 30 then axisinc = 2.5 * conversion_unit;
      else                         axisinc = 5   * conversion_unit;
    %end;
/* Otherwise, 'short' axis, 4-6 increments */
    %else %do;
      if      unit_range < 12 then axisinc = 2   * conversion_unit;
      else if unit_range < 18 then axisinc = 3   * conversion_unit;
      else if unit_range < 24 then axisinc = 4   * conversion_unit;
      else if unit_range < 30 then axisinc = 5   * conversion_unit;
      else                         axisinc = 10  * conversion_unit;
    %end;

/*Round the min's value to match the increment; if the number is */
/* rounded up so that it becomes larger than the lowest data value, */
/* decrease the min by one increment. */
  axislow = round(low,axisinc);
  if axislow > low then axislow = axislow - axisinc;
/* Round the max; if the number is rounded down, */
/* increase the max by one increment. */
  axishigh = round(high, axisinc);
  if axishigh < high then axishigh = axishigh + axisinc;
/* put the values into the global macro variables */
  call symput("&returned_min",compress(put(axislow, best.)));
  call symput("&returned_max",compress(put(axishigh, best.)));
  call symput("&returned_increment",compress(put(axisinc, best.)));
run;
%mend set_axis_minmaxincrement;