Какой самый быстрый способ разделения набора данных sas для пакетной обработки? - PullRequest
1 голос
/ 25 февраля 2012

У меня большой набор данных sas (1,5 мс, ~ 250 переменных), который мне нужно разбить на несколько меньших наборов данных sas одинакового размера для пакетной обработки. Каждый набор данных должен содержать все переменные, но только часть obs. Какой самый быстрый способ сделать это?

Ответы [ 2 ]

2 голосов
/ 25 февраля 2012

Вы можете сделать что-то вроде следующего:

%macro splitds(inlib=,inds=,splitnum=,outid=);

  proc sql noprint;
    select nobs into :nobs
    from sashelp.vtable
    where libname=upcase("&inlib") and memname=upcase("&inds");
  quit;
  %put Number of observations in &inlib..&inds.: &nobs;

  data %do i=1 %to &splitnum.;
         &outid.&i
       %end;;
    set &inds.;
    %do j=1 %to (&splitnum.-1);
      %if &j.=1 %then %do;
        if
      %end;
      %else %do;
        else if
      %end;
                _n_<=((&nobs./&splitnum.)*&j.) then output &outid.&j.;
    %end;
    else output &outid.&splitnum.;
  run;
%mend;

Пример вызова для разделения MYLIB.MYDATA на 10 наборов данных с именем NEWDATA1 - NEWDATA10 будет:

%splitds(inlib=mylib,inds=mydata,splitnum=10,outid=newdata);
1 голос
/ 25 февраля 2012

Попробуй это. Я еще не проверял, так что ожидайте ошибку где-нибудь. Вам нужно отредактировать вызов макроса для BATCH_PROCESS, чтобы включить имена наборов данных, количество новых наборов данных и т. Д.

%macro nobs (dsn);
   %local nobs dsid rc;
   %let nobs=0;
   %let dsid = %sysfunc(open(&dsn));
   %if &dsid %then %do;
      %let nobs = %sysfunc(attrn(&dsid,NOBS));
   %end;
   %else %put Open for dataset &dsn failed - %sysfunc(sysmsg());
   %let rc   = %sysfunc(close(&dsid));
   &nobs
%mend nobs;

%macro batch_process(dsn_in,dsn_out_prefix,number_of_dsns);

  %let dsn_obs = &nobs(&dsn_in);
  %let obs_per_dsn = %sysevalf(&dsn_obs / &number_of_dsns);

  data
     %do i = 1 %to &number_of_dsns;
        &dsn_out_prefix.&i
     %end;
     ;
     set &dsn_in;
     drop _count;
     retain _count 0;
     _count = _count + 1;
     %do i = 1 %to &number_of_dsns;
        if (1 + ((&i - 1) * &obs_per_dsn)) <= _count <= (&i * &obs_per_dsn) then do;
           output &dsn_out_prefix.&i;
        end; 
     %end;
  run;

%mend batch_process;

%batch_process( dsn_in=DSN_NAME , dsn_out_prefix = PREFIX_ , number_of_dsns = 5 );    
...