请选择 进入手机版 | 继续访问电脑版
楼主: priss111
3507 13

请问如何设置在同一个ID中循环? 谢谢! [推广有奖]

  • 0关注
  • 5粉丝

副教授

15%

还不是VIP/贵宾

-

威望
0
论坛币
153 个
通用积分
47.5396
学术水平
11 点
热心指数
14 点
信用等级
10 点
经验
14938 点
帖子
473
精华
0
在线时间
804 小时
注册时间
2008-3-30
最后登录
2024-3-16

priss111 发表于 2014-9-1 11:22:27 |显示全部楼层 |坛友微信交流群

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

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

经管之家联合CDA

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

感谢您参与论坛问题回答

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

+2 论坛币
想用循环找出同一个ID中state=5及其之后的一条记录。

请问如何设置该循环的第一步:使在同一个ID中循环?


data c;
  informat date1 yymmdd10.;
  format date1 yymmdd10.;
  input id $16. state yesno date1 ;
cards;
abcdefehhheehehe               1               1    2012-03-08
abcdefehhheehehe               1               1    2012-04-09
abcdefehhheehehe               1               1    2012-06-07
abcdefehhheehehe               1               1    2012-08-10
abcdefehhheehehe               1               1    2012-10-12
abcdefehhheehehe               5               1    2013-02-04
abcdefehhheehehe               1               1    2013-02-22
abcdefehhheehehe               1               1    2013-04-17
abcdefehhheehehe               1               1    2013-07-01
abcdefehhheehehe               1               1    2013-10-14
;
run;

二维码

扫码加我 拉你入群

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

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

关键词:informat informa format inform State 如何 记录

不用DO循环就可以实现:
proc sort data=c;
        by id;
run;

data c1;
        set c;
        by id;
        retain y;
        if state=5 then y+1;
        if y>0;
run;

你看一下是不是你想要的结果?
       

使用道具

priss111 发表于 2014-9-2 07:35:12 |显示全部楼层 |坛友微信交流群
huangpengfei 发表于 2014-9-1 19:16
不用DO循环就可以实现:
proc sort data=c;
        by id;
谢谢!

不是。

我没说清楚:
同一个ID要保留state=5的date1及state=5之后的第一条记录的date1,
最终要比较state=5及之后的第一条记录的date之间的时间间隔.

另外数据量比较大,
state=5只是其中一个小分类,
还想知道这种处理有没有有效的算法或者好的思路?或者说把同一个ID的纵向数据中不同条件下如何变成横向?

使用道具

pobel 在职认证  发表于 2014-9-2 08:46:24 |显示全部楼层 |坛友微信交流群
data d;
   set c;
   if state=5
      or (lag(state)=5 and id=lag(id));
run;

使用道具

priss111 发表于 2014-9-2 09:52:11 |显示全部楼层 |坛友微信交流群
pobel 发表于 2014-9-2 08:46
data d;
   set c;
   if state=5
tks!

lag()用法正适合。特别是 id=lag(id) 这个限制,很漂亮。

如果想保留state=5观察,同时生成一个新变量date5,使date5的值与将d数据集中state=1的date1的值相等即(date5=2013-02-22),有不想用first.id & last.id,该如何处理?
最终数据集为:
abcdefehhheehehe               5               1    2013-02-04  2013-02-22



*************************************;
如果想保留state=5之后所有state=1的观察中的最后一条记录,这个条件又该如何写?
或者类似的思路(算法)是否可以提示?

使用道具

pobel 在职认证  发表于 2014-9-2 10:57:44 |显示全部楼层 |坛友微信交流群
priss111 发表于 2014-9-2 09:52
tks!

lag()用法正适合。特别是 id=lag(id) 这个限制,很漂亮。
data d;
   set c;
   retain _state _yesno _date1;
   if state=5 then do;
      _state=state; _yesno=yesno; _date1=date1;
        end;
   if (lag(state)=5 and id=lag(id));
   date5=date1;
   state=_state;
   yesno=_yesno;
   date1=_date1;
   drop _:;
run;

使用道具

pobel 在职认证  发表于 2014-9-2 11:05:06 |显示全部楼层 |坛友微信交流群
priss111 发表于 2014-9-2 09:52
tks!

lag()用法正适合。特别是 id=lag(id) 这个限制,很漂亮。
*************************************;
如果想保留state=5之后所有state=1的观察中的最后一条记录

data d;
   set c;
   by id;
   retain flag;
   if first.id then flag=0;
   if state=5 then flag=1;
   if flag=1 and state=1;
   drop flag;
run;

data e;
   set d;
   by id;
   if last.id;
run;

使用道具

priss111 发表于 2014-9-2 11:46:38 |显示全部楼层 |坛友微信交流群
pobel 发表于 2014-9-2 10:57
data d;
   set c;
   retain _state _yesno _date1;
tks!

很灵活!
data d;
   set c;

   format date5 yymmdd10.;

   retain _state _yesno _date1;
   if state=5 then do;
      _state=state; _yesno=yesno; _date1=date1;
        end;
   if (lag(state)=5 and id=lag(id));
   date5=date1;
   state=_state;
   yesno=_yesno;
   date1=_date1;
   drop _:;
run;



data d1;
   set c;
   by id;
   retain flag;
   if first.id then flag=0;
   if state=5 then flag=1;
   if flag=1 and state=1;
   drop flag;
run;

data e;
   set d1;
   by id;
   if last.id;
run;


data de;
        merge d(in=a) e(rename=(date1=datelast));
        by id;
        if a;
        run;


如果想最终生成DE数据集,
但要加一个条件 if (date5-date1)<=30 then do;
这个条件应该怎么加才能让整个程序连贯起来?


我没有这样do循环或者连贯的写代码的思路,
特别想在这方面取得进步。
请高手多多指点,谢谢!

使用道具

pobel 在职认证  发表于 2014-9-2 12:45:21 |显示全部楼层 |坛友微信交流群
是这样?
data de;
        merge d(in=a where=(date5-date1<=30))
              e(keep=id date1 rename=(date1=datelast));
        by id;
        if a;
run;

使用道具

priss111 发表于 2014-9-2 13:02:05 |显示全部楼层 |坛友微信交流群
pobel 发表于 2014-9-2 12:45
是这样?
data de;
        merge d(in=a where=(date5-date1
TKS!!

不是。

如果if date5-date1<=30这个条件不满足则 生成d1数据集及之后的代码都可以不要了。

使用道具

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

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

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

GMT+8, 2024-3-29 02:48