SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 1708|回复: 10
打印 上一主题 下一主题

就是不同!

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2010-7-27 00:34:24 | 只看该作者

就是不同!

[code:2n71sisn]*method 1;
proc sql; *Use average to repalce multiple values at same id,date and field;
        create table NoDup as
                select unique id, date, field, avg(value) as value from Dup group by id, date, field;
        quit;        *191035;
*method 2;
proc means data = Dup nway noprint;
        class  id date field;
        var value;
        output out = NoDup(drop = _type_ _freq_) mean = value;
run; *191030;[/code:2n71sisn]

两种方法得出的数据集的观测数居然不同。一个是191035, 另一个是191030. 为什么呢?sql所得到的数据集,有几个重复值。大家有什么建议呢?
我本以为是bug,然后重启sas,运行一遍,照旧。如果SAS还存在这种bug,哪,哪不可能吧。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2010-7-27 09:21:09 | 只看该作者

Re: 就是不同!

看不出问题 <!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2010-7-27 09:41:45 | 只看该作者

Re: 就是不同!

你的filed字段是否含有小数呢? SQL 和SAS的浮点数处理方式不一样,也许看似同一值,实则是两个值。。。。。。。。。。。。。。。(纯属瞎猜  <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D --> )
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2010-7-27 09:59:00 | 只看该作者

Re: 就是不同!

gzgoon完全正确。

下面可以证明,我提供了第三种方法,也是用的data步,结果充分说明data步和sql对浮点处理方式不一样,data步考虑到小数位比sql多,但是据我的经验,公司一般用data步来处理此类数据。

[code:1maeoe50]data dup;
input  id  date  field  value ;
cards;
1  2  0&#46;0001  10
1  2  0&#46;0001  10
1  2  0&#46;00001  10
1  2  0&#46;00001000001  10
1  3  0&#46;00001  10
1  3  0&#46;00001  10
1  3  0&#46;00003  10
1  3  0&#46;00003  10
1  3  0&#46;00003  10
;
run;
proc sql; *Use average to repalce multiple values at same id,date and field;
   create table NoDup1 as
      select unique id, date, field, avg(value) as value from Dup group by id, date, field;
   quit;   *191035;
*method 2;
proc means data = Dup nway ;
   class  id date field;
   var value;
   output out = NoDup2(drop = _type_ _freq_) mean = value;
run; *191030;

proc sort data=dup out=dup;
by         id date field;

data nodup3;
     set dup;
         by id date field;
         if  first&#46;field then  do; num=0;mean=0;end;
                num+1; mean+value;
         if last&#46;field then do;  value=mean/num; output; end;
run;[/code:1maeoe50]

ps:jingju老大,我拜托的事,怎么样了?  <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2010-7-27 10:03:00 | 只看该作者

Re: 就是不同!

另外如果不需要考虑太多的小数位的时候,SAS公司提供了很多好用的函数,来去掉不必要的小数位,如ceil,int之类的。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2010-7-27 10:59:42 | 只看该作者

Re: 就是不同!

一切的非字符型,非整数的变量来做为分组或者比较大小的运算都是不可靠的。。。。。。。。。。。。。把AVG后面加一个FORMAT吧。可能会好点。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2010-7-27 20:27:20 | 只看该作者

Re: 就是不同!

to sxlion
我在看。对你所描述的专业知识和统计知识的缺乏,使我读的很慢。不过,你的英语不错啊,可比我强。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
8#
 楼主| 发表于 2010-7-28 14:38:40 | 只看该作者

Re: 就是不同!

to jingju,哈哈, 拿我开玩笑了。  <!-- s:) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) -->
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
9#
 楼主| 发表于 2010-7-28 15:32:58 | 只看该作者

Re: 就是不同!

你们还讲悄悄话哦 <!-- s:shock: --><img src="{SMILIES_PATH}/icon_eek.gif" alt=":shock:" title="Shocked" /><!-- s:shock: -->
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
10#
 楼主| 发表于 2010-7-30 23:53:30 | 只看该作者

Re: 就是不同!

非常感谢大家的解答。关于运算的精度问题,大家的看法是对的。其中验证的方法之一即为:用proc compare来比较从proc means和sql得到的平均数的差别。
其实,如果我要是早些讲到我数据里的date是从excel里import的,或许很多人就会马上想到其中的原因。但是因为我没有意识到其中的关联性,故此没有提及这个后来被证明是很用的条件。
从excel里来的数据date,在sas数据步里是被赋予format的。由于或这或那的原因,从excel date读入sas的date,其真值,也就是说去掉format看到值,(虽然可能性很小),可能是带有小数位的,比如说,12345.558.....。但是当赋予format时,这些小数位并没有给sas 造成任何的转换不便,sas自动取用整数位,然后转换成date。正如各位已知的,sql使用真值来做分类(group by),所以自然12345.558 …^= 12345;但是proc means是用format来分类(class),如果这个变量具有format的话。所以对means而言,12345.588 = 12345,因为他们对应了同一个date。
这就是proc sql有更多的分类的原因了。我的解决方案即为在预先的数据步里,加入date = int(date); formate date11.; 的语句。果然,问题不再出现了。
我曾经为此call过sas技术支持,他的建议是在import中加入statement: usedate = yes ; 我没有实验,但是我怀疑其作用,因为import缺省的选项即为此。
这就是我费了一个下午的成果。希望对大家也有帮助。
我现在琢磨的是,为什么在读入excel的时候,这种的乱七八糟的东西可能,虽然可能性较小,发生。并且如何避免它。
JingJu
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|小黑屋|手机版|Archiver|SAS中文论坛  

GMT+8, 2026-2-4 03:27 , Processed in 0.093322 second(s), 20 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表