0

最初の年齢と 2 番目の年齢の差が 5 より大きいグループを検出しようとしています。たとえば、次のデータがある場合、年齢の差grp=1は 39 なので、そのグループを別のデータ セットに出力したい. grp4も同様です。

id  grp age sex
1   1   60  M
2   1   21  M
3   2   30  M
4   2   25  F
5   3   45  F
6   3   30  F
7   3   18  M
8   4   32  M
9   4   18  M
10  4   16  M

私の最初のアイデアは、それらを並べ替えてからgrp、のようなものを使用して年齢間の絶対値を取得することでしたif first.grp then do;。しかし、グループごとに1歳と2歳の間の絶対値を取得する方法がわかりません。または、実際にこれをどのように開始すればよいかわかりません。

前もって感謝します。

4

5 に答える 5

2

これが私がうまくいくと思う1つの方法です。

data have;
 input id $ grp $ age sex $;
 datalines;
1   1   60  M
2   1   21  M
3   2   30  M
4   2   25  F
5   3   45  F
6   3   30  F
7   3   18  M
8   4   32  M
9   4   18  M
10  4   16  M
;

proc sort data=have ;
 by grp descending age;
run;

data temp(keep=grp);
 retain old;
 set have;
 by grp descending age;
 if first.grp then old=age;
 if last.grp then do;
  diff=old-age;
  if diff>5 then output ;
 end;
run;

Data want;
 merge temp(in=a) have(in=b);
 by grp ;
 if a and b;
run;
于 2012-06-22T01:05:41.997 に答える
1

各グループの値を簡単に比較できるように、PROCTRANSPOSEを使用します。例えば:

data groups1;

 input id $ grp age sex $;
 datalines;
1   1   60  M
2   1   21  M
3   2   30  M
4   2   25  F
5   3   45  F
6   3   30  F
7   3   18  M
8   4   32  M
9   4   18  M
10  4   16  M
;
run;

proc sort data=groups1;
  by grp; /* This maintains age order */
run;

proc transpose data=groups1 out=groups2;
  by grp;
  var age;
run;

転置されたデータを使用すると、好きな比較を行うことができます(質問から正確に何が欲しいかわからないので、最初の2つの年齢を比較するだけです)。

/* With all ages of a particular group in a single row, it is easy to compare */
data outgroups1(keep=grp);
  set groups2;
  if abs(col1-col2)>5 then output;
run;

この場合、これは、適用される条件をすべて満たす(コードを動的に生成して含める)グループごとに個別のデータセットを作成するための私の好ましい方法です。

/* A separate data set per GRP value in OUTGROUPS1 */
filename dynacode catalog "work.dynacode.mycode.source";
data _null_;
  set outgroups1;
  file dynacode;
  put "data grp" grp ";";
  put "  set groups1(where=(grp=" grp "));";
  put "run;" /;
run;

%inc dynacode;
于 2012-06-22T13:50:15.603 に答える
0

1歳と2歳の違いを追いかけているのであれば、次のコードはこれらを抽出するためのかなり簡単な方法です。データセットを読み取ってグループを識別し、直接アクセス方法POINT=を使用して関連するレコードを抽出します。レコードが1つしかないグループがある場合に備えて、grp = lag(grp)という追加の条件を設定します。

data want;
set have;
by grp;
if first.grp then do;
    num_grp=0;
    outflag=0;
    end;
outflag+ifn(lag(first.grp)=1 and grp=lag(grp) and abs(dif(age))>5,1,0) /* set flag to determine if group meets criteria */;
if not first.grp then num_grp+1; /* count number of records in group */
if last.grp and outflag=1 then do i=_n_-num_grp to _n_;
    set have point=i; /* extract required group records */
    drop num_grp outflag;
    output;
    end;
run;
于 2012-06-22T14:37:29.013 に答える
0

SQL アプローチを次に示します (CarolinaJay のコードを使用してデータセットを作成します)。

data groups1;

 input id grp age sex $;
 datalines;
1   1   60  M
2   1   21  M
3   2   30  M
4   2   25  F
5   3   45  F
6   3   30  F
7   3   18  M
8   4   32  M
9   4   18  M
10  4   16  M
;
run;

proc sql noprint;
  create table xx as
  select a.*
  from groups1 a
  where grp in (select b.grp
                from groups1 b
                join groups1 c  on c.id = b.id+1
                               and c.grp = b.grp
                               and abs(c.age - b.age) > 5
                left join groups1 d  on d.id = b.id-1
                                    and d.grp = b.grp
                where d.id eq .
               )
  ;   
quit;

C の結合は、同じグループ内の後続のレコードが 5 を超える絶対値を持つすべてのオカレンスを検出します。D の結合 (および where 句) は、レコードが最初のレコードである場合にのみ、C の結合の結果のみを考慮するようにします。グループに記録します。

于 2012-06-25T15:03:46.437 に答える
0
data have;
input id $ grp $ age sex $;
datalines;
1   1   60  M
2   1   21  M
3   2   30  M
4   2   25  F
5   3   45  F
6   3   30  F
7   3   18  M
8   4   32  M
9   4   18  M
10  4   16  M
;

data want;
  do i = 1 by 1 until(last.grp);
    set have;
by grp notsorted;
if first.grp then cnt = 0;
cnt + 1;
    if cnt = 1 then age1 = age;
if cnt = 2 then age2 = age;
diff = sum( age1, -age2 );
  end;
 do until(last.grp);
     set have;
 by grp;
 if diff > 5 then output;
 end;
 run;
于 2012-06-27T03:24:45.940 に答える