楼主: tj0412ymy
4677 10

[问答] 为字段做flag疑问 (50论坛币奖励!!!) [推广有奖]

  • 2关注
  • 48粉丝

已卖:4314份资源

副教授

65%

还不是VIP/贵宾

-

威望
0
论坛币
11512 个
通用积分
12.7575
学术水平
72 点
热心指数
91 点
信用等级
64 点
经验
29292 点
帖子
545
精华
0
在线时间
1203 小时
注册时间
2009-3-10
最后登录
2024-2-15

楼主
tj0412ymy 发表于 2013-6-6 11:34:28 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

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

经管之家联合CDA

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

感谢您参与论坛问题回答

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

+2 论坛币
问题:

ID

DES

Flag

1001

A

-3

1001

D

-2

1001

G

-1

1001

Target1

0

1001

K

1

1001

Y

2

1001

I

3

1002

H

-1

1002

Target1

0

1002

Target2

0

1002

Target3

0

1002

E

1

1002

Target1

0

1002

W

1

1002

Q

2



1. ID可看成是分组字段;
2. 只要字段DES中包含字符串'Target',则设置flag=0,且在同一ID内该位置以上观测的分别设置flag=-1,-2,...,该位置以下观测的分别设置flag=1,2,...
3. 若在同一ID内,包含Target的观测不是连续的,那么2个Target之间的观测对应的flag值(正负由哪个Target决定?)应由包含Target最长的部分决定 (比如在示例中ID=1002,E对应的flag值应为1,而不是-1。若2部分的长度相等,则设flag为正值。)
请高手给予指点!解答被采用的最佳解答者将获50论坛币奖励!
二维码

扫码加我 拉你入群

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

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

关键词:50论坛币 Flag 0论坛币 lag Fla 字符串

回帖推荐

邓贵大 发表于2楼  查看完整内容

kind of an overkill for such a well-stated problem.

本帖被以下文库推荐

对SAS和统计方面感兴趣的朋友,请加SAS学习和认证讨论群:169157207。欢迎在群上讨论!

沙发
邓贵大 发表于 2013-6-6 13:13:15
  1. data hell;
  2.         input ID $ DES $;
  3. datalines;
  4. 1001 A
  5. 1001 D
  6. 1001 G
  7. 1001 Target1
  8. 1001 K
  9. 1001 Y
  10. 1001 I
  11. 1002 H
  12. 1002 Target1
  13. 1002 Target2
  14. 1002 Target3
  15. 1002 E
  16. 1002 Target1
  17. 1002 W
  18. 1002 Q
  19. ;
  20. data hell1 hell2;
  21.         length prev_DES $ 8;
  22.         call missing(prev_DES, flag);
  23.         *count forward;
  24.         do _n_=1 by 1 until(last.ID);
  25.                 set hell;
  26.                 by ID;
  27.                 if find(DES, 'target', 'i') then do;
  28.                         flag = 0;
  29.                         if find(prev_DES, 'target', 'i') then streak=streak+1;
  30.                         else streak = 1;
  31.                 end;
  32.                 else do;
  33.                         if flag ne . then flag = flag + 1;
  34.                 end;
  35.                 output hell1;
  36.                 prev_DES = DES;
  37.         end;
  38.         lastobs+_N_;

  39.         call missing(prev_DES, flag);
  40.         *count backward;
  41.         do pos=lastobs to lastobs-_n_+1 by -1;
  42.                 set hell(keep=DES) point=pos;
  43.                 if find(DES, 'target', 'i') then do;
  44.                         flag = 0;
  45.                         if find(prev_DES, 'target', 'i') then streak=streak+1;
  46.                         else streak = 1;
  47.                 end;
  48.                 else do;
  49.                         if flag ne . then flag = flag - 1;
  50.                 end;
  51.                 output hell2;
  52.                 prev_DES = DES;
  53.         end;
  54.         keep ID DES flag streak;
  55. run;


  56. data hell3;
  57.         do _n_=1 by 1 until(last.ID);
  58.                 set hell1(keep=ID DES);
  59.                 by ID;
  60.         end;
  61.         lastobs + _n_;
  62.         do _n_=1 by 1 until(last.ID);
  63.                 set hell1(keep=ID DES flag streak);
  64.                 by ID;
  65.                 pos = lastobs - _n_ + 1;
  66.                 set hell2(keep=ID flag streak rename=(flag=flag2 streak=streak2)) point=pos;
  67.                 if streak2>streak then flag = flag2;
  68.                 output;
  69.         end;
  70.         keep ID DES flag;
  71. run;
复制代码
kind of an overkill for such a well-stated problem.
已有 6 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
jingju11 + 5 + 5 + 5 精彩帖子-so skilled...
Imasasor + 100 + 100 + 3 + 1 + 3 鼓励积极发帖讨论
webgu + 60 + 60 + 1 + 1 + 1 精彩帖子
scarfacetony + 1 + 1 + 1 精彩帖子
boe + 1 + 1 + 1 Great Overkill
tj0412ymy + 1 + 1 + 1 我很赞同

总评分: 经验 + 160  论坛币 + 160  学术水平 + 12  热心指数 + 10  信用等级 + 12   查看全部评分

Be still, my soul: the hour is hastening on
When we shall be forever with the Lord.
When disappointment, grief and fear are gone,
Sorrow forgot, love's purest joys restored.

藤椅
邓贵大 发表于 2013-6-6 14:00:44
I don't know if it's easier for one to understand with sorting.
  1. data hell;
  2.         input ID $ DES $;
  3. datalines;
  4. 1001 A
  5. 1001 D
  6. 1001 G
  7. 1001 Target1
  8. 1001 K
  9. 1001 Y
  10. 1001 I
  11. 1002 H
  12. 1002 Target1
  13. 1002 Target2
  14. 1002 Target3
  15. 1002 E
  16. 1002 Target1
  17. 1002 W
  18. 1002 Q
  19. ;
  20. proc means data=hell noprint nway;
  21.         class DES;
  22.         output out=DES(keep=DES);
  23. data ctrl;
  24.         retain fmtname 'DES' type 'c';
  25.         set DES(rename=(DES=start));
  26.         if find(start, 'target', 'i') then label='1';
  27.         else label = '0';
  28. proc format cntlin=ctrl;

  29. data backward;
  30.         do n=1 by 1 until(last.ID);
  31.                 set hell;
  32.                 by ID;
  33.                 output;
  34.         end;
  35. proc sort data=backward;
  36.         by ID descending n;

  37. %macro count(in=, out=);
  38. data &out;
  39.         do until(last.ID);
  40.                 do until(last.DES);
  41.                         set ∈
  42.                         by ID DES notsorted groupformat;
  43.                         format DES $DES.;
  44.                         if vvalue(DES) = '1' then do;
  45.                                 flag = 0;
  46.                                 if first.DES then streak = 0;
  47.                                 streak = streak + 1;
  48.                         end;
  49.                         else do;
  50.                                 if flag ne . then flag = flag + 1;
  51.                         end;
  52.                         output;
  53.                 end;
  54.         end;
  55. run;
  56. %mend;
  57. %count(in=hell, out=forward);
  58. %count(in=backward, out=backward);

  59. proc sort data=backward;
  60.         by ID n;

  61. data hell;
  62.         merge forward backward(rename=(flag=flag2 streak=streak2));
  63.         if streak2>streak then flag=-flag2;
  64.         keep ID DES flag;
  65.         format DES;
  66. run;
复制代码
已有 1 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
webgu + 40 + 40 + 1 + 1 + 1 热心帮助其他会员

总评分: 经验 + 40  论坛币 + 40  学术水平 + 1  热心指数 + 1  信用等级 + 1   查看全部评分

Be still, my soul: the hour is hastening on
When we shall be forever with the Lord.
When disappointment, grief and fear are gone,
Sorrow forgot, love's purest joys restored.

板凳
tj0412ymy 发表于 2013-6-6 14:10:21
邓贵大 发表于 2013-6-6 13:13
kind of an overkill for such a well-stated problem.
Many thanks. Very useful and powerful method.
对SAS和统计方面感兴趣的朋友,请加SAS学习和认证讨论群:169157207。欢迎在群上讨论!

报纸
邓贵大 发表于 2013-6-6 14:49:03
tj0412ymy 发表于 2013-6-6 14:10
Many thanks. Very useful and powerful method.
An overkill is an overkill. If no ID is repeated for more than 32767 times, then we can use a binary string to cut the length of code. Arrays would work if some IDs have > 32767 rows.
  1. data hell;
  2.         input ID $ DES $;
  3. datalines;
  4. 1001 A
  5. 1001 D
  6. 1001 G
  7. 1001 Target1
  8. 1001 K
  9. 1001 Y
  10. 1001 I
  11. 1002 H
  12. 1002 Target1
  13. 1002 Target2
  14. 1002 Target3
  15. 1002 E
  16. 1002 Target1
  17. 1002 Target1
  18. 1002 Target1
  19. 1002 Target1
  20. 1002 W
  21. 1002 Q
  22. ;
  23. data hell;
  24.         length str $ 32767;
  25.         do n=1 by 1 until(last.ID);
  26.                 set hell;
  27.                 by ID;
  28.                 if find(DES, 'target', 'i') then substr(str,n,1)='1'; else substr(str,n,1)='0';
  29.         end;
  30.         length prev_DES $ 8;

  31.         do _n_=1 by 1 until(last.ID);
  32.                 set hell;
  33.                 by ID;
  34.                 if find(DES, 'target', 'i') then do;
  35.                         flag = 0;
  36.                         if find(prev_DES, 'target', 'i') then streak=streak+1;
  37.                         else streak = 1;
  38.                         flag2 = 0;
  39.                 end;
  40.                 else do;
  41.                         if flag ne . then flag = flag + 1;

  42.                         next1 = findc(str,'1',_n_);
  43.                         if next1>0 then do;
  44.                                 next2 = findc(str,'0',next1);
  45.                                 if next2 > 0 then streak2 = next2-next1; else streak2 = n-next1;
  46.                                 flag2 = _n_-next1;
  47.                         end;
  48.                 end;
  49.                 prev_DES = DES;
  50.                 output;
  51.         end;
  52.         keep ID DES flag flag2 streak streak2;
  53. run;
  54. data hell;
  55.         set hell;
  56.         if streak2>streak then flag=flag2;
  57.         keep ID DES flag;
  58. run;
复制代码
Be still, my soul: the hour is hastening on
When we shall be forever with the Lord.
When disappointment, grief and fear are gone,
Sorrow forgot, love's purest joys restored.

地板
tj0412ymy 发表于 2013-6-6 15:22:54
邓贵大 发表于 2013-6-6 14:49
An overkill is an overkill. If no ID is repeated for more than 32767 times, then we can use a bi ...
Awesome hard skill on Data Step.
对SAS和统计方面感兴趣的朋友,请加SAS学习和认证讨论群:169157207。欢迎在群上讨论!

7
scarfacetony 发表于 2013-6-6 16:31:07
新手水平,写了个很山寨的……
————————————
这个是错的,保留原代码(思路 ),楼下才是正解
  1. data hell;
  2.         input ID $ DES $;
  3. datalines;
  4. 1001 A
  5. 1001 D
  6. 1001 G
  7. 1001 Target1
  8. 1001 K
  9. 1001 Y
  10. 1001 I
  11. 1002 H
  12. 1002 Target1
  13. 1002 Target2
  14. 1002 Target3
  15. 1002 E
  16. 1002 Target1
  17. 1002 W
  18. 1002 Q
  19. ;
  20. run;

  21. data hell;
  22.         set hell;
  23.         count+1;
  24. run;

  25. data z1;
  26.         set hell;
  27.         by id;
  28.         if find(des,'target','i') then do;
  29.                 x=count;
  30.                 flag=0;
  31.                 end;
  32.                 else flag+1;
  33. run;

  34. proc sql;
  35.         create table z1_1 as select *, min(x) as minx from z1 group by id;
  36. quit;

  37. data z1_2;
  38.         set z1_1;
  39.         if count-minx<0 then flag=count-minx;
  40.                 else flag=flag;
  41. run;
  42.         
  43. proc sort data=z1_2(keep=id des flag count); by count; run;
复制代码
已有 2 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
webgu + 60 + 60 + 1 + 1 + 1 精彩帖子
xulimei1986 + 1 + 1 + 1 我很赞同

总评分: 经验 + 60  论坛币 + 60  学术水平 + 2  热心指数 + 2  信用等级 + 2   查看全部评分

看了这个视频,我于是有了进股市的信心!
https://bbs.pinggu.org/thread-2787427-1-1.html

8
邓贵大 发表于 2013-6-6 21:46:21
scarfacetony 发表于 2013-6-6 16:31
新手水平,写了个很山寨的……
great idea so counting backwards is avoided, but you still have to count the # of consecutive TARGETs within each ID, otherwise case 3 stated by the OP cannot be properly handled.
  1. data hell;
  2.         input ID $ DES $;
  3. datalines;
  4. 1001 A
  5. 1001 D
  6. 1001 G
  7. 1001 Target1
  8. 1001 K
  9. 1001 Y
  10. 1001 I
  11. 1002 H
  12. 1002 Target1
  13. 1002 Target2
  14. 1002 Target3
  15. 1002 E
  16. 1002 Target1
  17. 1002 Target1
  18. 1002 Target1
  19. 1002 Target1
  20. 1002 Target1
  21. 1002 W
  22. 1002 Q
  23. ;
  24. run;

  25. data z1;
  26.         length prev_DES $ 8;
  27.         do until(last.id);
  28.         set hell;
  29.         by id;
  30.                 count+1;
  31.         if find(des,'target','i') then do;
  32.                         if find(prev_des,'target','i')=0 then streak=1; else streak = streak + 1;
  33.             flag=0;
  34.         end;
  35.         else do;
  36.                         if find(prev_des,'target','i') then subid+1;
  37.                         flag+1;
  38.                 end;
  39.                 output;
  40.                 prev_DES = DES;
  41.         end;
  42. run;

  43. proc sql;
  44.         create table z1_1 as select id,subid as subid, min(count) as minx, max(streak) as streak2
  45.                         from z1
  46.                         where flag=0
  47.                         group by id,subid;
  48. quit;

  49. data z1_2(/*keep=ID DES flag*/);
  50.         merge z1(in=in1) z1_1;
  51.                 by id subid;
  52.                 if find(des, 'target', 'i')=0 then do;
  53.                 if streak2>streak then flag=count-minx;
  54.         end;
  55. run;
复制代码
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
scarfacetony + 1 + 1 + 1 多谢指点

总评分: 学术水平 + 1  热心指数 + 1  信用等级 + 1   查看全部评分

Be still, my soul: the hour is hastening on
When we shall be forever with the Lord.
When disappointment, grief and fear are gone,
Sorrow forgot, love's purest joys restored.

9
殷秀霞 发表于 2013-6-6 22:38:24
不懂,不是这方面的专家啊

10
热成型065 发表于 2013-6-13 09:40:41
学习,学习~

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

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2026-1-4 01:46