楼主: rockfido
4573 27

请教关于SAS DATA处理问题 [推广有奖]

  • 0关注
  • 0粉丝

博士生

29%

还不是VIP/贵宾

-

威望
0
论坛币
2774 个
通用积分
0.1841
学术水平
1 点
热心指数
1 点
信用等级
0 点
经验
2421 点
帖子
199
精华
0
在线时间
199 小时
注册时间
2008-8-29
最后登录
2021-4-23

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

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

经管之家联合CDA

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

感谢您参与论坛问题回答

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

+2 论坛币
TYPE VALUE
A    1
A    49
A    23
B    44
B    2
C    3
C    4
C    10
请教这样一个DATA SET,有没有办法只用一个DATA STEP(或者尽可能少的STEP)就增加一个VARIABLE MEAN_
DEVIATION,就是用VALUE的值,减去这个值所在的TYPE的那个组的平均值?
二维码

扫码加我 拉你入群

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

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

关键词:Data Deviation Data step Variable value 请教 SAS Data

回帖推荐

bobguy 发表于5楼  查看完整内容

You need to load data twice, one for mean calculation and one for variance calculation. Here is one in data step. However, SAS/SQL provides a much simpler solution. data have; input TYPE $ VALUE; datalines; A 1 A 49 A 23 B 44 B 2 C 3 C 4 C 10 ; data wanted; do until (end); sum=0; do i=1 by 1 until(last.type); set have end=end; ...

pobel 发表于3楼  查看完整内容

data have; input TYPE $ VALUE; datalines; A 1 A 49 A 23 B 44 B 2 C 3 C 4 C 10 ; data wanted; if 0 then set have; declare hash hh(); hh.definekey("Type"); hh.definedata("Type","sum","n"); hh.definedone(); do until(end1); set have end=end1; if hh.find()=0 then do; sum=sum(sum,value); n+1; hh.replace(); ...

本帖被以下文库推荐

沙发
mxx2000 发表于 2010-5-28 05:04:34 |只看作者 |坛友微信交流群
要两个吧,一个proc mean 一个data step

使用道具

藤椅
pobel 在职认证  发表于 2010-5-28 08:15:50 |只看作者 |坛友微信交流群
data have;
        input TYPE $ VALUE;
        datalines;
A    1
A    49
A    23
B    44
B    2
C    3
C    4
C    10
;

data wanted;
    if 0 then set have;
        declare hash hh();
          hh.definekey("Type");
          hh.definedata("Type","sum","n");
          hh.definedone();
        do until(end1);
       set have end=end1;
           if hh.find()=0 then do;
              sum=sum(sum,value);
                  n+1;
                  hh.replace();
           end;
           else do;
              sum=value;
                  n=1;
          hh.add();
           end;
        end;
        do until(end2);
           set have end=end2;
           rc=hh.find();
           Mean_deviation=value-sum/n;
           output;
        end;
        keep type value mean_deviation;
        stop;
run;
已有 1 人评分经验 论坛币 收起 理由
bakoll + 3 + 3 精彩帖子

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

使用道具

板凳
yz7891 发表于 2010-5-28 10:33:36 |只看作者 |坛友微信交流群
  1. data a;
  2. input type $ value;
  3. datalines;
  4. A 1
  5. A 49
  6. A 23
  7. B 44
  8. B 2
  9. C 3
  10. C 4
  11. C 10
  12. ;
  13. run;
  14. proc sql;
  15.   create table b as
  16.     select type,value,avg(value) as avg,value-avg(value) as diff
  17.     from a
  18.     group by type
  19.   ;
  20. quit;
复制代码



                 The SAS System           10:29 Thursday, May 28, 2010   2

                            Obs    type    value      avg        diff

                             1      A        23     24.3333     -1.3333
                             2      A         1     24.3333    -23.3333
                             3      A        49     24.3333     24.6667
                             4      B         2     23.0000    -21.0000
                             5      B        44     23.0000     21.0000
                             6      C         4      5.6667     -1.6667
                             7      C         3      5.6667     -2.6667
                             8      C        10      5.6667      4.3333

使用道具

报纸
bobguy 发表于 2010-5-28 11:30:32 |只看作者 |坛友微信交流群
rockfido 发表于 2010-5-28 04:51
TYPE VALUE
A    1
A    49
A    23
B    44
B    2
C    3
C    4
C    10
请教这样一个DATA SET,有没有办法只用一个DATA STEP(或者尽可能少的STEP)就增加一个VARIABLE MEAN_
DEVIATION,就是用VALUE的值,减去这个值所在的TYPE的那个组的平均值?
You need to load data twice, one for mean calculation and one for variance calculation. Here is one in data step. However, SAS/SQL provides a much simpler solution.

data have;
        input TYPE $ VALUE;
        datalines;
A    1
A    49
A    23
B    44
B    2
C    3
C    4
C    10
;

data wanted;
do until (end);
sum=0;
do i=1 by 1 until(last.type);
    set have end=end;
    by type;
    sum+value;
    if last.type then mean=sum/i;
end;

do i=1 by 1 until(last.type);
    set have end=end;
    by type;
    var=(mean-value)**2;
   output;
end;

end;
stop;
drop sum i;
run;

proc print;run;

使用道具

地板
soporaeternus 发表于 2010-5-28 13:11:19 |只看作者 |坛友微信交流群
我比较好奇的是为什么只能用data步.......而且要尽量少......
Let them be hard, but never unjust

使用道具

7
crackman 发表于 2010-5-28 13:12:54 |只看作者 |坛友微信交流群
楼主想挑战一下楼上几位的技术

使用道具

8
yatming 发表于 2010-5-28 18:01:39 |只看作者 |坛友微信交流群
好方法都让楼上写了,所以写了个超繁琐的,调用了9.0中sas开始投产的javaobj,不过研究了下,这obj貌似没什么用,很多都可以用hash来实现,有兴趣者可以试试。楼主这题不适用,明显sql是最好的了。

sas:
  1. data result;
  2.         
  3.         if _N_=1 then do;
  4.                 declare javaobj h("mhash");
  5.                 do until (last);
  6.                         set x end=last;
  7.                         h.callVoidMethod("put",type, value);
  8.                 end;
  9.         end;

  10.         set x;

  11.         h.callDoubleMethod("get",type, avg);
  12.         mean_deviation=value-avg;

  13. run;
复制代码
java:想也没想写的,很烂,应该用更好的类来封装
  1. import java.util.*;
  2. import java.lang.*;

  3. public class mhash
  4. {
  5.   public Hashtable sumtable;
  6.   public Hashtable cnttable;

  7.   public mhash()
  8.   {
  9.     sumtable = new Hashtable();
  10.     cnttable = new Hashtable();
  11.   }

  12.   public void put(String key, double value)
  13.   {
  14.                   if(!sumtable.containsKey(key)) {
  15.               sumtable.put(key, new Double(value));
  16.               cnttable.put(key, new Double(1));
  17.             }else{
  18.                     double temp = ((Double)sumtable.get(key)).doubleValue() ;
  19.                     double tmp = ((Double)cnttable.get(key)).doubleValue() ;
  20.                     temp=temp+value;
  21.                     tmp=tmp+1;
  22.                     sumtable.put(key, new Double(temp));
  23.                     cnttable.put(key, new Double(tmp));
  24.             }
  25.   }


  26.   public double get(String key)
  27.     {
  28.       double x = ((Double)sumtable.get(key)).doubleValue() ;
  29.       double y = ((Double)cnttable.get(key)).doubleValue() ;
  30.       return x/y;
  31.     }

  32. }
复制代码
此方法已被soporaeternus 鄙视。
推广一下,有兴趣者不妨玩玩。不过本人觉得应用广度不是太广。
已有 2 人评分学术水平 热心指数 收起 理由
cloveror + 1 + 1 精彩帖子
crackman + 1 精彩帖子

总评分: 学术水平 + 1  热心指数 + 2   查看全部评分

使用道具

9
rockfido 在职认证  发表于 2010-5-28 20:22:19 |只看作者 |坛友微信交流群
牛B的。学习到了很多!

为什么只能用一个DATA STEP。。。。其实本来是就只可以用一个DATA STEP,因为自己怎么也做不出来,就很想知道,有啥办法可以搞定。。。。

使用道具

10
jingju11 发表于 2010-5-28 21:08:06 |只看作者 |坛友微信交流群
1# rockfido
纯属个人观点:
SAS 是应用性软件。如果要展示编程水平,SAS在某种程度上满足不了你的要求。
统计理论贯穿整个软件的设计。所以但凡涉及到统计量的计算(常规的),总有某个对应的过程。你的问题即对应线性模型的预测值和残差。


  1. proc glm noprint;
  2. class  type;
  3. model value = type;
  4. output out = GLMout p = mean_ r = deviation;
  5. run;
  6. quit;
复制代码


另外,我感觉以上的一些程序没有考虑missing values.从常规来讲,缺失值不应该摊薄平均值。所以在计算n时,或许应该考虑一下为佳:

  1. n = sum(n, not missing(value))
复制代码
已有 2 人评分学术水平 热心指数 收起 理由
cloveror + 1 精彩帖子
crackman + 1 精彩帖子

总评分: 学术水平 + 1  热心指数 + 1   查看全部评分

使用道具

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

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

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

GMT+8, 2024-4-19 14:48