楼主: caibirdcnb
5451 21

[原创博文] 请问SAS能做面积图吗?如果可以,如何实现,谢谢! [推广有奖]

11
jingju11 发表于 2011-10-22 22:07:52 |只看作者 |坛友微信交流群
从你的数据来看,好像有的日期只有一个产品,有的有三个(oct9)。是吗?
京剧

使用道具

12
caibirdcnb 发表于 2011-10-23 22:32:36 |只看作者 |坛友微信交流群
谢谢你,京剧。
如下面数据所示,我的数据是这样的:先按日期,再按种类排序。例如,总共废品种类有ABCDE,想加等于1,但由于E是好品的代码,我删除了,只保留ABCD,所以每天的废品想加不等于1。另外,日期是不连续的,因为有些天没有生产(9-OCT~12-OCT)。还有,废品也不一定都有ABCD,原因是某些天投料少,废品只有ABCD中的1种至3种(12-OCT)。

  1. Date        Category Per
  2. 9-Oct        A        0.085
  3. 9-Oct        B        0.005
  4. 9-Oct        C        0.097
  5. 9-Oct        D        0.053
  6. 12-Oct        A        0.077
  7. 12-Oct        B        0.044
  8. 12-Oct        C        0.078
  9. 15-Oct        A        0.045
  10. 15-Oct        B        0.038
  11. 15-Oct        C        0.055
  12. 15-Oct        D        0.011
复制代码


按照上面数据,我最原始的思路是初始化所有行的lower=0,upper=Per,然后,再逐行判断,如果该行天数等于上一行,则lower=lag(upper),upper=lag(upper)+Per。如下面程序所示:
但由于lag函数的特殊性,这种办法未能成功。
  1. data have1;
  2.         set have
  3.         lower=0;
  4.         upper=amount;
  5.         if date = lag(date) then do;
  6.                 lower=lag(upper);
  7.                 upper=lag(upper)+amount;
  8.         end;
  9. run;
复制代码

于是我就想按照你的思路:创建1个数组初始化所有天数的第一个废品的lower=0,upper=lower+amount,接着将该upper的数值用于重置数组,使相同天第二个废品的lower等于第一个废品的upper。。。如此循环。
  1. data have1;
  2.         set have;
  3.         array t[5] _temporary_(5*0);
  4.         lower =t[date];
  5.         upper =lower +amount;
  6.         t[date] =upper;
  7. run;
复制代码
因此,我需要增加一列将日期转换为按顺序排列的自然数,这就是我需要date1转化为date2的原因。date2这一列用在t[date]这里,因为t[X]的X只能是整数。

date       date2
09OCT    1
09OCT    1
09OCT    1
10OCT    2
10OCT    2
11OCT    3
16OCT    4
16OCT    4
17OCT    5







使用道具

13
jingju11 发表于 2011-10-24 01:36:16 |只看作者 |坛友微信交流群
caibirdcnb 发表于 2011-10-23 22:32
谢谢你,京剧。
如下面数据所示,我的数据是这样的:先按日期,再按种类排序。例如,总共废品种类有ABCDE, ...
  1. data have;
  2. input category $ date date9.percent;
  3. datalines;
  4. A 09OCT2010 15
  5. B 09OCT2010 10
  6. C 09OCT2010 12
  7. A 10OCT2010 12
  8. B 10OCT2010 08
  9. A 12OCT2010 07
  10. ;
  11. proc sort data =have out =have1 nodupkey; by category date;
  12. run;

  13. proc transpose data =have1 out =have2;
  14. id date; format date;
  15. by category notsorted;
  16. var percent;
  17. run;
  18. proc transpose data =have2 out =have3;
  19. by category;
  20. var _:;
  21. run;

  22. *assume: no percent = 0 percent;
  23. data have4;
  24. set have3;
  25. by category notsorted;
  26. date =input(substrn(_name_, 2), best.);format date date9.;
  27. retain upper;
  28. if first.category then do;
  29.   lower =0; upper =sum(percent, 0);
  30. end;
  31. else do;
  32.   lower =upper; upper =sum(lower, percent);
  33. end;
  34. run;

  35. proc sgplot;
  36. bandplot x =date upper =upper lower =lower/group =categroy;
  37. series x =date y =upper/group =categroy;
  38. xaxis type =discrete;*equally spaced;
  39. run;
  40. quit;
复制代码
I have no way to test the code.
JingJu

使用道具

14
jingju11 发表于 2011-10-25 01:33:10 |只看作者 |坛友微信交流群
jingju11 发表于 2011-10-24 01:36
I have no way to test the code.
JingJu
This maybe works. jingju
  1. data have;
  2. input category $ date date9. percent;
  3. datalines;
  4. A 09OCT2010 15
  5. B 09OCT2010 10
  6. C 09OCT2010 12
  7. A 10OCT2010 12
  8. B 10OCT2010 08
  9. A 13OCT2010 12
  10. B 13OCT2010 08
  11. C 13OCT2010 07
  12. A 14OCT2010 10
  13. B 14OCT2010 03
  14. C 14OCT2010 07
  15. A 15OCT2010 07
  16. A 16OCT2010 04
  17. B 16OCT2010 09
  18. C 16OCT2010 07
  19. ;

  20. proc sort data =have out =have1 nodupkey; by category date;
  21. run;
  22. proc transpose data =have1 out =have2;
  23. id date; format date z10.;
  24. by category notsorted;
  25. var percent;
  26. run;

  27. proc transpose data =have2(drop =_name_) out =have3;
  28.   by category;
  29.   var _:;
  30.   proc sort; by _name_ category;
  31. run;


  32. *assume: no percent = 0 percent;

  33. data have4;
  34. set have3;
  35. by _name_ notsorted;
  36. date =input(substrn(_name_, 2), best.);format date date9.;
  37. retain upper;
  38. if first._name_ then do;
  39.   lower =0; upper =sum(col1, 0);
  40. end;
  41. else do;
  42.   lower =upper; upper =sum(lower, col1);
  43. end;
  44. run;


  45. proc sgplot data =have4;
  46. band x =date upper =upper lower =lower/group =category transparency =0.6;
  47. series x =date y =upper/group =category;
  48. xaxis grid type =discrete;*equally spaced;
  49. yaxis grid label ="% of defective products";
  50. run;
  51. quit;
复制代码

使用道具

15
caibirdcnb 发表于 2011-10-25 16:23:17 |只看作者 |坛友微信交流群
Jingju,非常感谢!

开始看到你的程序,我在想,为什么要做2次transpose呢?直接用first.variable(我之前不知道这个功能)不就可以作图了吗?
后来我调试程序中通过比较才发现,如果某天某个category没有废品,则band语句会把前后天该catetory的平均值当成该天的废品率(其实就是直线穿过)。
因此,需要先做个笛卡尔连接,补全所有废品。

我打算放弃2次transpose,做1个包括全部废品率的参考数据集,然后通过SQL语句做个笛卡尔连接。

真的非常感谢你的帮助。

使用道具

16
jingju11 发表于 2011-10-25 21:21:42 |只看作者 |坛友微信交流群
如果某天某个category没有废品,则band语句会把前后天该catetory的平均值当成该天的废品率(其实就是直线穿过)。
我不认为band plot 有这样的功能。直线穿过是不错的,其实他只是忽略了其中的点而已。另外,从你的题目本身来讲,用band plot没有赋予任何的意义,只是一种表达方法而已(许多人也许认为没有意义)。band plot的本义是往往连线之下的面积有意义。另外,你的每一条曲线代表的是累计的废品率。他的变化丝毫反应不出某一产品的变化。京剧

使用道具

17
jingju11 发表于 2011-10-25 21:24:00 |只看作者 |坛友微信交流群
所以这个band只是频率图的和的连线而已。这只是我的一点意见。京剧

使用道具

18
caibirdcnb 发表于 2011-10-26 10:58:10 |只看作者 |坛友微信交流群
jingju11 发表于 2011-10-25 21:21
我不认为band plot 有这样的功能。直线穿过是不错的,其实他只是忽略了其中的点而已。另外,从你的题目本 ...
Jingju,是我表达的不好,我的本意是对某个废品,如果第一天废品率10%,第二天是0,第三天是2%,如果没有先用笛卡尔连接把缺失的废品(0%)补全,则band plot由于在第二天数据missing,所以band看起来是1个倒着放的梯形,使第二天得废品率看起来像是6%。仅仅是图形这样,不是指band plot有那样的功能。

至于题目本身,使用band确实没有意义,我最初的想法是像看看所有废品中,每个废品的废品率的趋势图。最后图形看起来并不清晰。

使用道具

19
jingju11 发表于 2011-10-27 09:21:29 |只看作者 |坛友微信交流群
caibirdcnb 发表于 2011-10-26 10:58
Jingju,是我表达的不好,我的本意是对某个废品,如果第一天废品率10%,第二天是0,第三天是2%,如果没有 ...
我还以为我已经解决了这个问题。两次transpose+sum()方程。
京剧

使用道具

20
jingju11 发表于 2011-10-27 09:23:23 |只看作者 |坛友微信交流群
每个废品的废品率的趋势图。最后图形看起来并不清晰。
在你的图示里做不到这一点。因为是累加而成的曲线。也即是说upper依赖于lower。
京剧

使用道具

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

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

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

GMT+8, 2024-5-11 02:48