楼主: 伊ò太ジ刀
3727 18

[问答] 数据集如何做行与行之间的比较和整合 [推广有奖]

11
伊ò太ジ刀 发表于 2015-1-10 23:04:44
mingfeng07 发表于 2015-1-10 18:18
顺序复杂的情况好像解决不了?

例如:
A B 1
E E 2
C D 3
D A 4
E C 5

这5人都有直接或间接的亲属关系,出来的家庭号需要相同才行。

12
teqel 发表于 2015-1-10 23:15:22
伊ò太ジ刀 发表于 2015-1-10 23:04
顺序复杂的情况好像解决不了?

例如:
想到一个无聊的办法:
1. 让x1和x2交换,就是总有x1<x2
2. 对x1进行sort

13
伊ò太ジ刀 发表于 2015-1-10 23:22:12
teqel 发表于 2015-1-10 23:15
想到一个无聊的办法:
1. 让x1和x2交换,就是总有x1
什么意思,不太明白呢,x1和x2不是数字,没有大小关系吧。就算是数字,交换后也不一定是x1<x2吧。

大神能说得详细点吗?

14
teqel 发表于 2015-1-10 23:57:07
试试这个
  1. data a;
  2. input x1$ x2$  id;
  3. cards;
  4. A B 1
  5. B C 2
  6. C D 3
  7. E F 4
  8. G F 5
  9. A B 1
  10. E E 2
  11. C D 3
  12. D A 4
  13. E C 5
  14. ;
  15. run;


  16. data b(drop=i j num k1 k2 x1 x2 id);
  17. array arr{7} A B C D E F G;
  18. num=0;
  19. do i=1 to tot;
  20.         set a nobs=tot;
  21.         do j=1 to 7;
  22.                 if vname(arr[j])=(x1) then k1=j;
  23.                 if vname(arr[j])=(x2) then k2=j;
  24.         end;
  25.         if missing(arr[k1]) and missing(arr[k2]) then
  26.                 do;
  27.                         num+1;
  28.                         arr[k1]=num;
  29.                         arr[k2]=num;
  30.                 end;
  31.         else if missing(arr[k1]) then arr[k1]=arr[k2];
  32.         else if missing(arr[k2]) then arr[k2]=arr[k1];
  33. end;
  34. run;

  35. proc transpose data=b out=c(rename=(_name_=Person col1=Family));
  36. run;
复制代码

15
teqel 发表于 2015-1-10 23:59:42
上面程序唯一的缺陷就是人名太多的时候要一一列举,可以用SQL+MACRO改进

16
mingfeng07 学生认证  发表于 2015-1-11 00:47:43
伊ò太ジ刀 发表于 2015-1-10 23:04
顺序复杂的情况好像解决不了?

例如:
  1. data a;
  2. input x1 $   x2    $     id;
  3. label x1="投保人" x2="被保人" id="单号";
  4. cards;
  5. A B 1
  6. E E 2
  7. C D 3
  8. D A 4
  9. E C 5
  10. ;
  11. run;
  12. data a(drop=t);
  13. set a;
  14. if x1>=x2 then do;
  15. t=x1;x1=x2;x2=t;
  16. end;
  17. run;
  18. proc sort data=a;by x1;run;
  19. data b;
  20. length value $1000;
  21. set a;
  22. retain value '';
  23. if indexc(value,compress(x1),compress(x2))=0 then t+1;
  24. value=compress(value)||compress(x1)||compress(x2);
  25. label x1="人员号" t="家庭号";
  26. run;
  27. data want;
  28. set b(keep=x1 t) b(keep=x2 t rename=(x2=x1));
  29. run;
  30. proc sort data=want nodupkey;by x1;run;
复制代码

17
伊ò太ジ刀 发表于 2015-1-11 13:52:20
mingfeng07 发表于 2015-1-11 00:47
data a(drop=t);
set a;
if x1>=x2 then do;
t=x1;x1=x2;x2=t;
end;
run;

proc sort data=a;by x1;run;

这段很精妙,是关键的一步,之后proc sort是不是也应该要 sort by x1 x2才行?
而且好像下面这情况又出问题了:
A B      A B
E E      A D
D A =>A F
E F      E E
F A      E F
去到第4行E就会被判定为新家庭了?





18
伊ò太ジ刀 发表于 2015-1-11 13:53:18
teqel 发表于 2015-1-10 23:15
想到一个无聊的办法:
1. 让x1和x2交换,就是总有x1
1. 让x1和x2交换,就是总有x1<x2

这步好像挺关键,它的具体意义是什么?

19
wpfwxn 发表于 2015-1-12 16:10:53
伊ò太ジ刀 发表于 2015-1-10 20:21
要怎么写?
既然你问了,我就尝试写一下吧
data a;
  input g1 $ g2 $ x;
  cards;
A        B        1
B        C        2
C        D        3
E        F        4
G        F        5
;
run;

proc sort; by g1 g2; run;
data b;
  set a;
  retain str n; length str $200;
  array glst g1 g2;
  if count(str, g1, 't') = 0 and count(str, g2, 't') = 0 then do;
      n + 1;
          str = compbl(g1||g2||str);
          id = compress('0'||n);
          group = g1;output;
          group = g2;output;
  end;

  else do;
    do over glst;
      if count(str, glst, 't') = 0 then do;
            str = compbl(glst||str);
            id = compress('0'||n);
            group = glst;output;
      end;
    end;
  end;
  keep group id;
run;
           

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

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