875 3

[问答] 如何只保留想要的观测 [推广有奖]

  • 0关注
  • 0粉丝

高中生

57%

还不是VIP/贵宾

-

威望
0
论坛币
9 个
通用积分
0.4500
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
305 点
帖子
12
精华
0
在线时间
35 小时
注册时间
2019-10-29
最后登录
2022-10-17

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

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

经管之家联合CDA

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

感谢您参与论坛问题回答

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

+2 论坛币
求教大神,假如有这样一组数据:
ID    SIG
1      正常
1      正常
1      异常有临床意义
1      异常有临床意义
1      异常无临床意义
1      正常
1      正常
2      正常
2      正常
2     异常有临床意义
2     正常
2     正常
2     正常

2     异常有临床意义
2     正常

对于每个ID,只想保留SIG第一次出现异常有临床意义到到不再出现异常有临床意义的最后一次正常,比如对于ID为1的数据来说,要保留3~6行,对于ID为2的数据来说要保留3~8行,如何编程
二维码

扫码加我 拉你入群

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

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


没想到什么好办法,写着写着就变的复杂了。

data have;
input ID    SIG $20.;
cards;
1      正常
1      正常
1      异常有临床意义
1      异常有临床意义
1      异常无临床意义
1      正常
1      正常
2      正常
2      正常
2     异常有临床意义
2     正常
2     正常
2     正常
2     异常有临床意义
2     正常
;run;
data want_1;
        set have;
        by id;
        if first.id then do;
                rows=0;
                flg=0;
        end;
        rows+1;
        if sig='异常有临床意义' then flg+1;
        if flg>0;

run;

proc sql ;
        create table work.want_2 as select t1.id,min(t1.rows) as normal_min_rows
                from work.want_1 t1
                        ,(select id,max(rows) as max_rows
                                from work.want_1
                                where sig='异常有临床意义'
                                group by id) t2
        where t1.id=t2.id
        and t1.rows>t2.max_rows
        and t1.sig='正常'
        group by t1.id;
quit;

data want;
        merge work.want_1 work.want_2;
        by id;
        if rows<=normal_min_rows;
        keep id sig;
run;
已有 1 人评分经验 收起 理由
eijuhz + 20 精彩帖子

总评分: 经验 + 20   查看全部评分

使用道具

藤椅
whymath 发表于 2021-4-4 12:54:51 |只看作者 |坛友微信交流群
要方便的进行倒序查找,建议使用多重set或hash技巧:
data have;
input ID    SIG $20.;
cards;
1      正常
1      正常
1      异常有临床意义
1      异常有临床意义
1      异常无临床意义
1      正常
1      正常
2      正常
2      正常
2     异常有临床意义
2     正常
2     正常
2     正常
2     异常有临床意义
2     正常
3      正常
3     异常有临床意义
3     异常有临床意义
3      正常
3     异常无临床意义
;run;

data want(drop=tmp:);
  set have;
  by id notsorted;

  retain csfn;    *此前存在cs记录的标识;
  if first.id then csfn = .;
  if sig = '异常有临床意义' then csfn = 1;

  do i = rec to 1 by -1;    *此前cs记录已经转变为正常的标识;
    set have(rename=(id=tmpid sig=tmpsig)) nobs=rec point=i;
    if id=tmpid and tmpsig = '异常有临床意义' then leave;
    else if id=tmpid and tmpsig = '正常' and _N_>i then csfn = .;
  end;
run;

使用道具

  1. data test1;
  2.     set test;
  3.         by id;
  4.         n+1;
  5.         if first.id then n=1;
  6. run;

  7. proc sql;
  8.     * 找出第一次和最后一次异常有临床意义的位置;  
  9.     create table  test2 as select id,  max(n) as last, min(n) as first from test1 where sig="异常有临床意义" group by id;
  10.         create table test3 as select * from test1 a full join test2 b on a.id=b.id where a.sig="正常" and a.n>b.last;
  11.         * 找出最后一次异常有临床意义后的第一个正常位置;
  12.         create table test4 as select distinct id, first,  min(n) as normal_first from test3 group by id;
  13. quit;

  14. data total;
  15.     merge test1(in=a) test4;
  16.         by id;
  17.         if a;
  18.     if first<=n<=normal_first;
  19. run;
复制代码

使用道具

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

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

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

GMT+8, 2024-4-27 21:29