SAS中文论坛

标题: 就是不同! [打印本页]

作者: shiyiming    时间: 2010-7-27 00:34
标题: 就是不同!
[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,哪,哪不可能吧。
作者: shiyiming    时间: 2010-7-27 09:21
标题: Re: 就是不同!
看不出问题 <!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->
作者: shiyiming    时间: 2010-7-27 09:41
标题: Re: 就是不同!
你的filed字段是否含有小数呢? SQL 和SAS的浮点数处理方式不一样,也许看似同一值,实则是两个值。。。。。。。。。。。。。。。(纯属瞎猜  <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D --> )
作者: shiyiming    时间: 2010-7-27 09:59
标题: 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 -->
作者: shiyiming    时间: 2010-7-27 10:03
标题: Re: 就是不同!
另外如果不需要考虑太多的小数位的时候,SAS公司提供了很多好用的函数,来去掉不必要的小数位,如ceil,int之类的。
作者: shiyiming    时间: 2010-7-27 10:59
标题: Re: 就是不同!
一切的非字符型,非整数的变量来做为分组或者比较大小的运算都是不可靠的。。。。。。。。。。。。。把AVG后面加一个FORMAT吧。可能会好点。
作者: shiyiming    时间: 2010-7-27 20:27
标题: Re: 就是不同!
to sxlion
我在看。对你所描述的专业知识和统计知识的缺乏,使我读的很慢。不过,你的英语不错啊,可比我强。
作者: shiyiming    时间: 2010-7-28 14:38
标题: Re: 就是不同!
to jingju,哈哈, 拿我开玩笑了。  <!-- s:) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) -->
作者: shiyiming    时间: 2010-7-28 15:32
标题: Re: 就是不同!
你们还讲悄悄话哦 <!-- s:shock: --><img src="{SMILIES_PATH}/icon_eek.gif" alt=":shock:" title="Shocked" /><!-- s:shock: -->
作者: shiyiming    时间: 2010-7-30 23:53
标题: 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
作者: shiyiming    时间: 2010-7-31 00:01
标题: Re: 就是不同!
to sxlion
非也非也。不是说笑。如果要我写,我是决然写不出这么好的东西来的。但是,或许杂志的编辑们希望看到更多的细节,比如如何分类的,分类是如何的具体不同的。这只是我的不知两文钱的意见。JingJu




欢迎光临 SAS中文论坛 (https://mysas.net/forum/) Powered by Discuz! X3.2