SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 870|回复: 8
打印 上一主题 下一主题

如何找数据中某些观测的(有附加条件的)前一个观测并计数

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2009-9-16 04:50:17 | 只看该作者

如何找数据中某些观测的(有附加条件的)前一个观测并计数

有这样一组数据, 已经按ID 和 date 排好顺序。

ID        date        A        B         C        Nr
001        2003.12        0        1        1        1
001        2005.9        1        4        1        2
002        2004.12        0        2        1        3
002        2006.3        1        3        0        4
002        2007.12        1        5        0        5
002        2008.12        1        3        0        6
003        2006.6        1        1        0        7
004        2004.12        0        6        1        8
004        2008.12        1        5        0        9




真实数据几十万行,没有 ”Nr”(序号) 这一列,为了叙述方便,加了这一列。

要求:1)如果A=1, 就要找到与这一行相同ID的前一行观测, 如:Nr. 2 的A=1, 它的前一观测应为Nr.1, 又如:Nr. 7 的A=1, 但它没有与它相同ID 的前一观测。
2)如果在第一步中找到的前一观测的B=5, 那么这一观测将忽略不计,而找它的前一观测且B不等于5才算找到。如:Nr. 6 的前一观测应为Nr.5, 而Nr.5的B=5, 所以Nr.6 的前一观测实际应为 Nr.4。
3)按照上面两步的要求全部找到前一观测后,将该观测的C值与前一观测的C值进行比较,C的取值只有0和1,如果两个观测的C相同,那么不计数,如果两个观测的C值不同,就把它算作一个并计数,最后计算出整个数据中一共存在多少个这样的观测(它的C值与前一观测的C值不同)。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2009-9-16 10:31:02 | 只看该作者

Re: 如何找数据中某些观测的(有附加条件的)前一个观测并计数

不太明白,如果只要结果不要过程的话,把B=5的观测去掉,问题就简单多了
[code:2bufe6jp]data raw;
        input ID date $ A B C Nr;
datalines;
001 2003.12 0 1 1 1
001 2005.9 1 4 1 2
002 2004.12 0 2 1 3
002 2006.3 1 3 0 4
002 2007.12 1 5 0 5
002 2008.12 1 3 0 6
003 2006.6 1 1 0 7
004 2004.12 0 6 1 8
004 2008.12 1 5 0 9
;

data temp;
        set raw(where=(b ne 5));
        by id;
        lag_c=lag(c);
        if first.id=0 then
                do;
                        bxor_c=bxor(c,lag_c);
                        if bxor_c=1 then output;
                end;
run;

data _null_;
        dsid=open('temp','i');
        n=attrn(dsid,'nobs');
        put "*** " n "***";
run;[/code:2bufe6jp]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2009-9-16 17:42:38 | 只看该作者

Re: 如何找数据中某些观测的(有附加条件的)前一个观测并计数

data step and lag function...........
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2009-9-16 20:26:08 | 只看该作者

Re: 如何找数据中某些观测的(有附加条件的)前一个观测并计数

[quote:3cug7hli]...如果只要结果不要过程的话,把B=5的观测去掉,问题就简单多了[/quote:3cug7hli]

如果此处B=5而且A=1。此观测应用于寻找它的前一次观测值,而不是简单的删除.
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2009-9-16 22:06:26 | 只看该作者

Re: 如何找数据中某些观测的(有附加条件的)前一个观测并计数

<!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->  那位大侠有好主意指点一下吧
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2009-9-17 02:13:55 | 只看该作者

Re: 如何找数据中某些观测的(有附加条件的)前一个观测并计数

[b:22d4x75w]感谢hopewell 和byes 两位Experts [/b:22d4x75w]的回复。

hopewell 的答案没有把第一条的要求考虑进去。所以显得很简单。也可能是在叙述要求是没表述清楚,我在试一下:

不是找每一行观测的前一个任意的观测。用lag是可以找到前一观测,但它的ID必须和这一观测的ID相同才可以,如果不同,等于没有前一观测,用缺失表示。

还使用sas说话吧,一目了然。 下面这段运用了hopewell的主意,顺便说一句:[b:22d4x75w][u:22d4x75w]HOPEWELL你真棒[/u:22d4x75w][/b:22d4x75w]。


data Basis;
        set raw end=endf;
        retain ii;
                if first.id=0 then
                        do;       
                                lag_c=lag(c);
                                if a=1 then do;       
                                bxor_c=bxor(c,lag_c);
                         if bxor_k =1 then ii+1;
                     end;
        end;
        if endf then put ii;
run;
解决了上述问题,但是没能解决B=5 这项。
向所有参与探讨的人致敬。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2009-9-17 07:10:17 | 只看该作者

Re: 如何找数据中某些观测的(有附加条件的)前一个观测并计数

[code:lr2k0my0]
data raw;
   input ID date $ A B C Nr;       
datalines;
001 2003&#46;12 0 1 1 1
001 2005&#46;9 1 4 1 2
001 1234&#46;4 1 1 1 1
002 2004&#46;12 0 2 1 3
002 2006&#46;3 1 3 0 4
002 2007&#46;12 1 5 0 5
002 2008&#46;12 1 3 0 6
003 2006&#46;6 1 1 0 7
004 2004&#46;12 0 6 1 8
004 2008&#46;12 1 5 0 9
005 2004&#46;12 0 2 1 3
005 2006&#46;3 1 3 0 4
005 2007&#46;12 1 5 0 5
005 2008&#46;12 1 3 0 6
005 2006&#46;6 1 1 0 7
005 2004&#46;12 0 6 1 8
005 2008&#46;12 1 5 0 9
006 2003&#46;12 0 1 1 1
006 2005&#46;9 1 4 1 2
006 1234&#46;4 1 1 1 1
006 2004&#46;12 0 2 1 3
006 2006&#46;3 1 3 0 4
006 2007&#46;12 1 5 0 5
006 2008&#46;12 1 3 0 6
006 2006&#46;6 1 1 0 7
006 2004&#46;12 0 6 1 8
006 2008&#46;12 1 5 0 9
006 2004&#46;12 0 2 1 3
006 2006&#46;3 1 3 0 4
006 2007&#46;12 1 5 0 5
006 2008&#46;12 1 3 0 6
006 2006&#46;6 1 1 0 7
006 2004&#46;12 0 5 1 8
006 2008&#46;12 1 5 0 9
;
;
run;

data temp;
   set raw;
   by id;
   retain a1 b1 c1 &#46;;
        if first&#46;id then do;
                if b ^=5 then do;
                        a1=a; b1=b; c1=c;
                end;
                delete;
        end;         
   if a=1 and b1 ^=5 then do;
                output;
           if b ^=5 then do;
                        a1=a; b1=b; c1=c;           
                end;
        end;
        else if b ^=5 then do;
           a1=a; b1=b; c1=c;
           delete;
        end;

run;

data temp1;
        set temp end=endof;
        if ^missing(c1) then if c ^=c1 then count+1;
        if endof then put '# of interested obs=' count;

run;

proc print;run;
[/code:lr2k0my0]
第一code未必对;第二code即使对,也不简练。我感觉我的测试数据没有代表性。A B C 为需要前一观测的观测;A1 B1 C1 为前一观测。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
8#
 楼主| 发表于 2009-9-17 11:18:41 | 只看该作者

Re: 如何找数据中某些观测的(有附加条件的)前一个观测并计数

[code:2f7cgwfo]data ahuige;
    input ID$ date A B C Nr;
    cards;
001 2003&#46;12 0 1 1 1
001 2005&#46;9 1 4 1 2
002 2004&#46;12 0 2 1 3
002 2006&#46;3 1 3 0 4
002 2007&#46;12 1 5 0 5
002 2008&#46;12 1 3 0 6
003 2006&#46;6 1 1 0 7
004 2004&#46;12 0 6 1 8
004 2008&#46;12 1 5 0 9
;
run;

data final(drop=prevC prevID);
    set ahuige;
    retain prevC prevID;
    if a=1 and prevID=id then if c^=prevC then flag=1;
    if  b^=5 then        do;  prevID=id; prevC=c; end;
    totalflagnum+flag;
run;[/code:2f7cgwfo]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
9#
 楼主| 发表于 2009-9-17 12:47:55 | 只看该作者

Re: 如何找数据中某些观测的(有附加条件的)前一个观测并计数

<!-- s:lol: --><img src="{SMILIES_PATH}/icon_lol.gif" alt=":lol:" title="Laughing" /><!-- s:lol: --> ahuige 大师出手了,又在跟jingju11比看谁写的最短呢吧
大概看懂了,唬的我还以为加个prev前缀就能自动赋值呢 <!-- s:o --><img src="{SMILIES_PATH}/icon_surprised.gif" alt=":o" title="Surprised" /><!-- s:o -->
[code:3e8xbcc0]data final;
    set ahuige;
    retain prevC prevID;
        /* 先判断,后retain值 */
    if a=1 and prevID=id then if c^=prevC then flag=1; /* 在id组内a值为1时,判断条件,计数变量加1 */
    if  b^=5 then      /* 在b不等于5的情况下retain变量c和id的值 */  
                do;  
                        prevID=id;
                        prevC=c;
                end;
    totalflagnum+flag; /* 求总计 */
run;[/code:3e8xbcc0]
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-2-5 23:14 , Processed in 0.157953 second(s), 20 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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