0

次のような SAS データセットがあります。

id | dept | ...
1    A
2    A
3    A
4    A
5    A
6    A
7    A
8    A
9    B
10   B
11   B
12   B
13   B

各観察は人を表します。

データセットを「チーム」データセットに分割したいと思います。各データセットは最大 3 つの観測値を持つことができます。

上記の例では、部門 A 用に 3 つのデータセットを作成することになります (これらのデータセットのうち 2 つには 3 つの観測が含まれ、3 つ目のデータセットには 2 つの観測が含まれます)。部門 B の 2 つのデータセット (1 つは 3 つの観測を含み、もう 1 つは 2 つの観測を含む)。

そのようです:

最初のデータセット (deptA1):

id | dept | ...
1    A
2    A
3    A

2 番目のデータセット (deptA2)

id | dept | ...
4    A
5    A
6    A

3 番目のデータセット (deptA3)

id | dept | ...
7    A
8    A

4 番目のデータセット (deptB1)

id | dept | ...
9    B
10   B
11   B

5 番目のデータセット (deptB2)

id | dept | ...
12   B
13   B

私が使用している完全なデータセットには、50 部門を超える何千もの観測が含まれています。部門ごとに必要なデータセットの数を計算できます。必要なデータセットの数は動的であるため、マクロを使用するのが最善の方法だと思います。しかし、最大 3 つの観測値を持つようにデータセットを作成するロジックがわかりません。どんな助けでも感謝します。

4

2 に答える 2

1

別のバージョン。DavBバージョンと比較すると、入力データを1回だけ処理し、単一のデータステップで複数のテーブルに分割します。また、より複雑な分割ルールが必要な場合は、データステップビューWORK.SOURCE_PREPで実装できます。

data WORK.SOURCE;
infile cards;
length ID 8 dept $1;
input ID dept;
cards;
1    A
2    A
3    A
4    A
5    A
6    A
7    A
8    A
9    B
10   B
11   B
12   B
13   B
14   C
15   C
16   C
17   C
18   C
19   C
20   C
;
run;

proc sort data=WORK.SOURCE;
by dept ID;
run;

data  WORK.SOURCE_PREP / view=WORK.SOURCE_PREP;
set WORK.SOURCE;
by dept;
length table_name $32;

if first.dept then do;
    count = 1;
    table = 1;
end;
else count + 1;

if count > 3 then do;
    count = 1;
    table + 1;
end;
/* variable TABLE_NAME to hold table name */
TABLE_NAME = catt('WORK.', dept, put(table, 3. -L));
run;

/* prepare list of tables */
proc sql noprint;
create table table_list as
select distinct TABLE_NAME from WORK.SOURCE_PREP where not missing(table_name)
;
%let table_cnt=&sqlobs;
select table_name into :table_list separated by ' ' from table_list;
select table_name into :tab1 - :tab&table_cnt from table_list;
quit;

%put &table_list;

%macro loop_when(cnt, var);
    %do i=1 %to &cnt;
        when ("&&&var.&i") output &&&var.&i;
    %end;
%mend;

data &table_list;
set WORK.SOURCE_PREP;
    select (TABLE_NAME);
        /* generate OUTPUT statements */
        %loop_when(&table_cnt, tab)
    end;
run;
于 2013-02-19T15:41:19.620 に答える
1

これを試すことができます:

%macro split(inds=,maxobs=);

  proc sql noprint;
    select distinct dept into :dept1-:dept9999
    from &inds.
    order by dept;
    select ceil(count(*)/&maxobs.) into :numds1-:numds9999
    from &inds.
    group by dept
    order by dept;
  quit;
  %let numdept=&sqlobs;

  data %do i=1 %to &numdept.;
         %do j=1 %to &&numds&i;
           dept&&dept&i&&j.
         %end;
       %end;;
    set &inds.;
    by dept;
    if first.dept then counter=0;
    counter+1;
    %do i=1 %to &numdept.;
      %if &i.=1 %then %do;
        if
      %end;
      %else %do;
        else if
      %end;
                dept="&&dept&i" then do;
      %do k=1 %to &&numds&i.;
        %if &k.=1 %then %do;
          if
        %end;
        %else %do;
          else if
        %end;
                 counter<=&maxobs.*&k. then output dept&&dept&i&&k.;
      %end;
      end;
    %end;
  run;
%mend split;

%split(inds=YOUR_DATASET,maxobs=3);

%SPLIT マクロ呼び出しの INDS パラメータ値を入力データ セットの名前に置き換えるだけです。

于 2013-02-19T15:29:19.927 に答える