Split SAS dataset

后端 未结 2 1324
挽巷
挽巷 2021-01-17 02:00

I have a SAS dataset that looks like this:

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
         


        
相关标签:
2条回答
  • 2021-01-17 02:42

    You could try this:

    %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);
    

    Just replace the INDS parameter value in the %SPLIT macro call to the name of your input data set.

    0 讨论(0)
  • 2021-01-17 02:58

    Another version. Compared to DavB version, it only processes input data once and splits it into several tables in single datastep. Also if more complex splitting rule is required, it can be implemented in datastep view 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;
    
    0 讨论(0)
提交回复
热议问题