楼主: caibirdcnb
18995 22

[问答] SAS新手求助关于SGPLOT如何画条形图 谢谢 [推广有奖]

  • 0关注
  • 36粉丝

讲师

47%

还不是VIP/贵宾

-

威望
0
论坛币
1367 个
通用积分
16.5538
学术水平
67 点
热心指数
70 点
信用等级
64 点
经验
6762 点
帖子
206
精华
2
在线时间
433 小时
注册时间
2011-8-31
最后登录
2023-9-23

相似文件 换一批

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
各位高手,请问如何根据上边的数据生成下边的图形,想把GRADE1/2/3放在同一个轴上叠加起来,而不是分成3个柱子。
非常感谢!
raw data.jpg chart.jpg

我求助前也看了SAS的帮助文档,但似乎只有数据格式如下表的时候才能实现上图。而这样的整合的话,我的数据就太长了,300多W个观测,有3个GRADE,总共就要变成900多W个了。
sas need format.jpg

其实,我的原始数据是以下格式,我增加了3个列分别叫GRADE1/2/3,例如,如果是G1,那么GRADE1的数值就等于1,否则等于0,然后再按照Date进行summary,就得到最上面的表格了。
根据下面这个数据格式,又如何实现上面的图形呢?非常感谢!
source format.jpg

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:sgplot gplot 新手求助 plot GPL 如何

回帖推荐

guoluo 发表于6楼  查看完整内容

应该没有很直接的方法,以下的方法供参考

本帖被以下文库推荐

沙发
caibirdcnb 发表于 2011-9-6 12:00:17 |只看作者 |坛友微信交流群
有没有高手能指点一下。非常感谢!

使用道具

藤椅
guoluo 发表于 2011-9-6 20:59:53 |只看作者 |坛友微信交流群
  1. data test;
  2.   input date: yymmdd. @;
  3.   do grade = 'G1','G2','G3';
  4.     input value @@;
  5.     output;
  6.   end;
  7.   format date yymmdds10.;
  8. cards;
  9. 2011/8/21 0.24 0.43 0.17
  10. 2011/8/22 0.06 0.50 0.20
  11. 2011/8/23 0.02 0.04 0.19
  12. 2011/8/24 0.14 0.27 0.15
  13. 2011/8/25 0.18 0.21 0.15
  14. 2011/8/26 0.28 0.28 0.14
  15. 2011/8/27 0.32 0.39 0.06
  16. 2011/8/28 0.03 0.39 0.09
  17. 2011/8/29 0.02 0.25 0.12
  18. 2011/8/30 0.07 0.28 0.09
  19. ;

  20. proc sgplot data=test;
  21. vbar date/response=value group=grade transparency=0.3;
  22. xaxis display=(nolabel);
  23. yaxis grid values=(0 to 0.9 by 0.1) display=(nolabel);
  24. keylegend/position=right;
  25. format date mmddyy4.;
  26. run;
复制代码
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
Tigflanker + 3 + 2 + 1 观点有启发

总评分: 学术水平 + 3  热心指数 + 2  信用等级 + 1   查看全部评分

使用道具

板凳
caibirdcnb 发表于 2011-9-7 23:41:17 |只看作者 |坛友微信交流群
guoluo,非常感谢!It works。
我是新手,所以还有很多问题要请教:
1. SAS生成的图片如何指定保存位置和格式?我目前只能在results窗口查看。谢谢!
2. 假设我有3W(实际中有300W)个高斯分布的0-30的数据,我想生成以下图形,请问用SAS如何实现?谢谢!
左轴是1个分布函数,右轴是概率密度。当然我分组比较小,理想情况是分为几十到上百组,这样曲线比较平滑。
CDF.jpg
我初步的想法是先bin为几十组到几百组数据,然后计算每个组有多少数量,再通过公式计算累积的百分比,如下表所示。
但我怀疑SAS说不定就自带函数可以一句话就实现。如果SAS没有自带函数,麻烦您给说个思路,我根据你的思路试着编写出来,遇到疑问再继续向您请教。谢谢了!

data.jpg

使用道具

报纸
caibirdcnb 发表于 2011-9-7 23:58:28 |只看作者 |坛友微信交流群
漏了1个,如果在右轴加上数量的折线图,应该如何实现呢?我试着先根据日期汇总数量,然后把每个数量放到G1/G2/G3上面去,然后再SGPLOT下面再增加SERIES X = Y =,但总是出错。谢谢!

另外,我想系统地学习SAS,请问应该怎么学起呢?我目前的水平是只看过the little sas book,但基本的东西都掌握不熟悉,几乎都要查这本书或者【帮助】确认语法没错,但对数据集进行排序,重新组合,合并等相对熟悉一些。
有没有什么捷径能让我认真学3、4个月后能较为熟练地编写程序?
我不是统计行业的,所以我对SAS应用到的地方基本就是:整理数据;简单统计数据,基本极限于平均值,标准差等;画图,常用的有趋势图,X-Y图,CDF图,类似X-Y图的bin_X-Y图,等高线图等。一般情况下我用的是JMP,但是数据量太大了,经常几百W个观测,几十列的表,而且数据源就是SAS数据集。所以熟悉SAS对工作会很有帮助。

使用道具

地板
guoluo 发表于 2011-9-8 22:03:28 |只看作者 |坛友微信交流群
应该没有很直接的方法,以下的方法供参考
  1. data test;
  2.   do i = 1 to 30000;
  3.     x = 15 + 4*rannor(12345);
  4.     output;
  5.   end;
  6. run;

  7. proc univariate data=test noprint;
  8.   histogram x /outhistogram= temp midpoints=0 to 30 by 0.5;
  9. run;

  10. data temp;
  11.   set temp;
  12.   density = _OBSPCT_/100;
  13.   prob + _OBSPCT_/100;
  14.   n = density * 30000;
  15. run;

  16. ods graphics on/imagefmt=jpg imagename='test'; /*in current fodler*/;
  17. *ods rtf file="c:\test.rtf";
  18. proc sgplot data=temp;
  19.   series x = _MIDPT_ y = prob/name='a' legendlabel='CDF';
  20.   series x = _MIDPT_ y = n/y2axis name='b' legendlabel='distribution';
  21.   xaxis display=(nolabel);
  22.   yaxis display=(nolabel) values=(0 to 1.1 by 0.1) grid;
  23.   y2axis display=(nolabel);
  24.   keylegend 'a' 'b'/position=right noborder;
  25. run;
  26. *ods rtf off;
复制代码
已有 1 人评分经验 论坛币 收起 理由
bakoll + 3 + 3 精彩帖子

总评分: 经验 + 3  论坛币 + 3   查看全部评分

使用道具

7
caibirdcnb 发表于 2011-9-13 21:17:44 |只看作者 |坛友微信交流群
guoluo,非常感谢你一直以来的耐心。

我根据你的思路写了一个画CDF的MACRO,不过我遇到一个致命的问题:如下面图片所示,CDF曲线是红色和蓝色,两条概率密度曲线应该也是相应颜色(浅红和浅蓝),所以我必须手动指定颜色。在下面这行代码中,我如果使用color =这个选项,1个Y轴只能指定1个颜色,也就是说,最终两条CDF曲线变成一种颜色,两条概率密度曲线变成另外一种颜色,而这并不能区分UP/DOWN。并且数据有时有很多组,所以我需要1个坐标轴指定多种颜色:红,蓝,绿,黄,紫;另1个坐标轴是浅红,浅蓝,浅绿,浅黄,浅紫。请问有办法实现吗?非常感谢!
series x = &_x y = cdf / group = &_by lineattrs = (pattern = solid thickness = 2 color =);

另外请教一下如何指定生成图片的大小,图片标题和各坐标轴标题字体的大小和样式。
(图片太大,放到PPT上要缩放,而且缩小的话,字体看起来太小了)
还有我想在图片空白的角落添加几行字,请问有什么方法可以实现,类似:
“U: ss = 1465546, mean = 4645, std = 456"
“D: ss = 1678546, mean = 8985, std = 234"

谢谢!

下面是我写的代码,见笑了。
  1. libname temp "H:\SAS";

  2. %CDF (_in = temp.test, _x = DATA, _by = UP_DOWN, _maverick_min = 0.05, _maverick_max = 0.25, _out =, _missing = -10);


  3. %macro CDF (_in =, _x =, _by =, _maverick_min =, _maverick_max =, _out =, _missing =);

  4. data _data_raw;
  5.         set &_in (keep = &_x &_by);
  6.         if &_x = . then &_x = &_missing;
  7.         else &_x = &_x;
  8. run;

  9. data _temp_no_maverick;
  10.         set _data_raw;
  11.         where &_x <= &_maverick_max and &_x >= &_maverick_min;
  12. run;

  13. %mmmmss (_in = _temp_no_maverick, _var = &_x);
  14. %axis_scale (var_mean = &_mean, var_std = &_std, var_min = &_min, var_max = &_max, scale_type = 'b');

  15. data _temp_bin;
  16.         set _data_raw;
  17.         bin = round(&_x, &_bin_step);
  18. run;

  19. proc report data = _temp_bin out = _temp_bin_sum (drop = _BREAK_ rename=(N = count)) nowindows;
  20.         column &_by bin N;
  21.         define &_by  /group;
  22.         define bin /group;
  23.         options nolabel;
  24. run;
  25. proc sort data = _temp_bin_sum;
  26. by &_by bin;
  27. run;

  28. proc report data = _temp_bin_sum out = _temp_qty (drop = _BREAK_ rename=(count = input)) nowindows;
  29.         column &_by count, sum;
  30.         define &_by / group;
  31.         options nolabel;
  32. run;

  33. data _data_sum (rename = (bin = &_x));
  34. merge _temp_bin_sum _temp_qty;
  35. by &_by;
  36.         per = 100 * count / input;
  37.         if &_by = lag1(&_by) then cdf + per;
  38.                 else cdf = per;
  39. run;

  40. %mmmmss (_in = _temp_no_maverick, _var = &_x);
  41. %axis_scale (var_mean = &_mean, var_std = &_std, var_min = &_min, var_max = &_max, scale_type = 'x');
  42. %mmmmss (_in = _data_sum, _var = count);
  43. %axis_scale (var_mean = &_mean, var_std = &_std, var_min = &_min, var_max = &_max, scale_type = 'y2');

  44. proc sgplot data = _data_sum;
  45.         series x = &_x y = cdf / group = &_by lineattrs = (pattern = solid thickness = 2);
  46.         series x = &_x y = count / y2axis group = &_by lineattrs = (pattern = solid thickness = 1);
  47.         xaxis label = '&_x' grid values = (&_axis_x_min to &_axis_x_max by &_axis_x_step);
  48.         yaxis label = 'Cumulative Distribution(%)' grid values = (0 to 100 by 10);
  49.         y2axis label = 'Distribution(N)' grid values = (0 to &_axis_y2_max by &_axis_y2_step);       
  50.         title "&_x CDF Plot by &_by";
  51. run;

  52. proc datasets library=work nolist;
  53.         delete  _temp_no_maverick _stat _temp_bin _temp_bin_sum _temp_qty _data_raw _data_sum;
  54. run;

  55. %mend CDF;


  56. *mmmmss stands for mean median min max std ss;
  57. %macro mmmmss(_in =, _var =);

  58. %global _mean _median _min _max _std _ss;

  59. proc means data = &_in noprint;
  60.         var &_var;
  61.         output out=_stat
  62.                 mean = _mean
  63.                 median = _median
  64.                 min = _min
  65.                 max = _max
  66.                 std = _std
  67.                 n = _ss;
  68. run;

  69. data _null_;
  70.    set _stat;
  71.    call symput('_mean', _mean);
  72.    call symput('_median', _median);
  73.    call symput('_min', _min);
  74.    call symput('_max', _max);
  75.    call symput('_std', _std);
  76.    call symput('_ss', _ss);
  77. run;

  78. %mend mmmmss;

  79. *bin the data and calculate the axis scale;
  80. %macro axis_scale (var_mean =, var_std =, var_min =, var_max =, scale_type =);

  81. %global _axis_x_min _axis_x_max _axis_x_step _axis_x2_min _axis_x2_max _axis_x2_step
  82.                                 _axis_y_min _axis_y_max _axis_y_step _axis_y2_min _axis_y2_max _axis_y2_step
  83.                                 _bin_step;

  84. data _null_;
  85.         if &scale_type = 'b' then
  86.                 do;
  87.                         axis_min = &var_mean - 3 * &var_std;
  88.                         if axis_min < 0 then
  89.                                 do;
  90.                                         axis_min = abs (axis_min);
  91.                                         axis_min = round (axis_min, 10 ** floor (log10 (axis_min)));
  92.                                         axis_min = 0 - axis_min;
  93.                                 end;
  94.                         else axis_min = round (axis_min, 10 ** floor (log10 (axis_min)));
  95.                         axis_max = &var_mean + 3 * &var_std;
  96.                         if axis_max < 0 then
  97.                                 do;
  98.                                         axis_max = abs (axis_max);
  99.                                         axis_max = round (axis_max, 10 ** floor (log10 (axis_max)));
  100.                                         axis_max = 0 - axis_max;
  101.                                 end;
  102.                         else axis_max = round (axis_max, 10 ** floor (log10 (axis_max)));
  103.                         axis_step = (axis_max - axis_min) / 50;
  104.                         axis_step = round (axis_step, 10 ** floor (log10 (axis_step)));
  105.                         call symput('_bin_step', axis_step);
  106.                 end;
  107.         else if &scale_type = 'x' then
  108.                 do;
  109.                         axis_min = &var_mean - 3 * &var_std;
  110.                         if axis_min < 0 then
  111.                                 do;
  112.                                         axis_min = abs (axis_min);
  113.                                         axis_min = round (axis_min, 10 ** (floor (log10 (axis_min)) - 1));
  114.                                         axis_min = 0 - axis_min;
  115.                                 end;
  116.                         else axis_min = round (axis_min, 10 ** (floor (log10 (axis_min)) - 1));
  117.                         axis_max = &var_mean + 3 * &var_std;
  118.                         if axis_max < 0 then
  119.                                 do;
  120.                                         axis_max = abs (axis_max);
  121.                                         axis_max = round (axis_max, 10 ** (floor (log10 (axis_max)) - 1));
  122.                                         axis_max = 0 - axis_max;
  123.                                 end;
  124.                         else axis_max = round (axis_max, 10 ** (floor (log10 (axis_max)) - 1));
  125.                         axis_step = (axis_max - axis_min) / 10;
  126.                         axis_step = round (axis_step, 10 ** floor (log10 (axis_step)));
  127.                         call symput('_axis_x_min', axis_min);
  128.                         call symput('_axis_x_max', axis_max);
  129.                         call symput('_axis_x_step', axis_step);
  130.                 end;
  131.         else if &scale_type = 'y2' then
  132.                 do;
  133.                         axis_min = 0;
  134.                         axis_max = &var_max * 1.1;
  135.                         axis_max = round (axis_max, 10 ** floor (log10 (axis_max)));
  136.                         axis_step = axis_max / 10;
  137.                         call symput('_axis_y2_min', axis_min);
  138.                         call symput('_axis_y2_max', axis_max);
  139.                         call symput('_axis_y2_step', axis_step);
  140.                 end;
  141. run;

  142. %mend axis_scale;
复制代码
Snap1.jpg

使用道具

8
guoluo 发表于 2011-9-16 22:17:35 |只看作者 |坛友微信交流群
1. lineattrs = (pattern = solid thickness = 2 color =red);
lineattrs = (pattern = solid thickness = 2 color =blue);
lineattrs = (pattern = solid thickness = 2 color =geen);
lineattrs = (pattern = solid thickness = 2 color =yellow);
/* proc registry list startat="COLORNAMES"; run; */
2. ods graphics on/width=10in height=7in imagefmt=jpg imagename='test';
3. proc sgplot ... inset "U: ss = 1465546, mean = 4645, std = 456"/noborder position=topleft;

使用道具

9
caibirdcnb 发表于 2011-9-17 21:24:48 |只看作者 |坛友微信交流群
非常感谢!但很不幸问题还是存在,请继续多多指教啊。
我的疑难在于:series x = aa y = bb / group = cc lineattrs = 这个语句中,lineattrs只能指定1种颜色,然而,由于group的存在,该语句产生了2条或者更多的线,显然,多条线仅指定一种颜色是不够的。谢谢!

我这几天仔细查阅了帮助,似乎有一种办法可以解决这个问题,但由于编程语法不熟悉,暂时还不知道怎么实现。
我的办法是:
1. 通过帮助知道系统默认的样式是style.default。
2. 通过帮助知道
style.default中,这种group的系列线,颜色是由样式GraphData1-12里面的ContrastColor属性决定的。
For grouped data, the default color is specified by the ContrastColor attribute of the GraphData1 ... GraphDatan style elements in the current style.
3. 通过下面查询语句逐步追踪,可知GraphData1-12的颜色是由'gcdata1'-'gcdata12'指定的,而'gcdata1'-'gcdata12'的具体值是12种RGB颜色。
实际使用表明,假设有4个组,则第一句series x = aa y = bb / group = cc使用的是'gcdata1'-'gcdata4'的颜色,而第二句series x = aa y = bb / group = cc y2axis使用的是'gcdata5'-'gcdata8'的颜色,依次类推。
  1. proc template;
  2.     source Styles.Default;
  3.    run;
复制代码
4. 基于上面的背景,我使用下面代码可以更改让GraphData1对应'gcdata5'而不是原来的'gcdata1',这样相当于我能指定颜色了。或者,我也可以直接更改'gcdata1'的RGB颜色。
  1. proc template;
  2.     define style nbCDFL;
  3.     parent=Styles.Default;
  4.     style Graph from Graph /   
  5.     OutputWidth = 7in
  6.     OutputHeight = 4.5in;
  7.     。。。更多语句。。。
  8. run;
复制代码
例1,如果我的组数有6组,则我可以通过上面代码(具体代码需要参考source Styles.Default)指定如下图的颜色,这样我只要在作图之前通过ods listing style = nbCDFL之类的语句就可以得到需要的颜色。
Snap2.jpg

例2,如果我的组数是3组,则我必须重新定义上图的颜色代码如下图(1和4,2和5,3和6)。
Snap3.jpg

5. 所以,我现在的难题在于组数不固定,所以gcdata1-12需要根据实际组数情况指定颜色。
我猜测可以通过类似下面的程序来指定gcdatan所对应的颜色,但是不知道怎么批量定义1批全局变量global.i。
  1. data _null_;
  2.         array c1; /*(具体指定上图左边6种颜色的RGB代码)*/
  3.         array c2; /*(具体指定上图右边6种颜色的RGB代码)*/

  4.         group = 3; /*假设这是组数*/
  5.        
  6.            do i= 1 to group; /*如果先初始化上面图表的12种颜色,则gcdata1至gcdata3不用指定,指定gcdata4-6即可*/
  7.                    global.i = c1{i};
  8.         end;

  9.            do i= group + 1 to group + group;
  10.                    global.i = c2{i-group};
  11.         end;
  12. run;
  13.        
  14.         *运行完上面程序global.1-global.7就是所需要的颜色
  15.          然后再把global.1-7赋予proc template过程里面的class或者style语句即可;
复制代码

谢谢!

使用道具

10
jingju11 发表于 2011-9-17 23:06:59 |只看作者 |坛友微信交流群
  1. %let _gcdata_L1 =r11 r12 r13 r14 r15 r16;
  2. %let _gcdata_L2 =r21 r22 r23 r24 r25 r26;
  3. %let _group =3;
  4. %macro colorList;       
  5.         %do i =1 %to &_group;
  6.                 "gcdata&i" =%scan(&_gcdata_L1, &i)
  7.                 "gcdata%eval(&i +&_group)" =%scan(&_gcdata_L2, &i)
  8.         %end;;
  9. %mend colorList;
  10. proc template;
  11.    define style styles.ChangedColors;
  12.    parent=styles.analysis;
  13.    style graphcolors from graphcolors /
  14.     %colorList;
  15.    end;
  16. run;
复制代码
很好的讨论。我猜想你最后的需要只是要通过macro产生改变color style所需要的文本而已。
京剧

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-19 19:56