SAS Proc GCHART等效于Proc GPLOT统一
有没有办法用proc gchart制作具有统一轴的多个条形图 在proc gplot中,我可以使用以下统一选项:SAS Proc GCHART等效于Proc GPLOT统一,sas,Sas,有没有办法用proc gchart制作具有统一轴的多个条形图 在proc gplot中,我可以使用以下统一选项: proc gplot data=test uniform; by state; plot var*date; run; 这将为所有使用相同轴范围的by变量提供一组绘图 proc gchart不存在此选项--是否有其他方法可以实现此目的?我不能只定义一个固定的范围,因为我的数据会变化。谢谢大家的输入。 由于proc本身似乎没有一个好的解决方案,所以我使用了一种宏方法来手动设置
proc gplot data=test uniform;
by state;
plot var*date;
run;
这将为所有使用相同轴范围的by变量提供一组绘图
proc gchart不存在此选项--是否有其他方法可以实现此目的?我不能只定义一个固定的范围,因为我的数据会变化。谢谢大家的输入。 由于proc本身似乎没有一个好的解决方案,所以我使用了一种宏方法来手动设置轴 本文为我所做的工作提供了基础: 因为除了那份不可搜索的PDF文件,我在任何地方都找不到该程序的文本,所以我在这里键入了它。“我的版本”添加了一个附加参数,可以选择填充下限值,以便在下限值下方为数据标签留出空间(如果正在制作标签位于正值上方和负值下方的柱状图,则此参数非常有用)
%宏集\u轴\u最小最大增量(ds=,
axisvar=,
轴长度=51,
sa_min=99999,
sa_max=-999999,
返回的最小值=轴最小值,
返回的最大值=轴最大值,
返回的增量=轴增量,
力0=0,
垫底=0
) ;
%全局和返回的最小值和返回的最大值和返回的增量;
/*找出高值和低值。注:使用了数据步骤而不是过程*/
/*允许应用选项参数(如果指定)*/
proc sort data=&ds out=sortlb(keep=&axisvar);
由&axisvar;
何处&n。;
跑
数据轴数据(保持低=高);
保持低0;
设置sortlb end=eof;
由&axisvar;
如果_n_=1,则低=&axisvar;
如果是eof,那么做;
高=&axisvar;
如果&sa_min^=99999和&sa_minhigh,则high=&sau max;
%如果&force_zero=1%,则为%do;
如果低>0,则低=0;
否则,如果高<0,则高=0;
%结束;
%如果&pad_bottom=1%,则为%do;
如果低<0,则低=低-((高-低)*.06);
%结束;
产出;
结束;
跑
数据轴数据;
设置数据;
/*确保“高”大于“低”*/
如果高,您有什么版本的SAS?如果是9.2+,你反对SGPLOT/SGPANEL吗?我对SGPLOT有一定的反对意见——这是使用9.2,它不能从SGPLOT获得很好的PDF矢量输出。我可以访问9.3来运行程序(并获得干净的SGPLOT输出),但我更喜欢在9.2中运行,这将进入一个带有一些proc GPLOTS的ODS布局,因此我尝试将其全部保留在同一个系列中(从未使用带注释和ODS布局的SGPLOT)。尝试了SGPLOT,我可以获得统一的轴,但我无法使它与GREPLAY一起工作(我用它来设置我的布局),所以我怀疑SG*函数已经过时了。嗯,GREPLAY不能与SGPLOT一起工作。如果你有9.3,我建议在长期学习GTL时,它可以让你更容易地做很多这方面的事情(包括接管GREPLAY功能来定义布局,接管axis的统一性等等)。
%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;