Эффективное объединение многих наборов данных sas

У меня более 200 тыс. Небольших наборов данных с одинаковыми переменными (n <1000 и обычно п <100) что я хочу объединить в основной набор данных. Я попытался использовать макрос, который использует шаг данных, чтобы просто перебрать все новые наборы данных и объединить с мастером с помощью "установить мастер новый: ", но это занимает очень много времени. Кроме того, если я пытаюсь запустить одновременно, шаг выполнения данных вызова говорит о том, что у меня недостаточно памяти на огромном сервере. Для справки, все небольшие наборы данных вместе составляют чуть более 5 гигабайт. Любые предложения будут ценны. Вот что у меня так далеко:

%macro catDat(name, nbr) ;
    /*call in new dataset */
    data new ;
    set libin.&name ;
    run ;

    /* reorder names */
    proc sql noprint;
    create table new as 
    select var1, var2, var3
    from new;
    quit;

    %if &nbr = 1 %then %do ;
        data master;
        set new;
        run;
    %end; 
    %if &nbr > 1 %then %do ;
        data master;
        set master new ;
        run;
    %end ;
%mend;

/* concatenate datasets */
data runthis ;
set datasetNames ;
call execute('%catdat('||datasetname||','||_n_||')');
run;

Решено: увидеть Бобакомментарии ниже.

 Jim Crozier18 нояб. 2012 г., 19:10
Извините, Боб, это всего лишь пример. Я обновил код выше.
 BellevueBob18 нояб. 2012 г., 19:06
Является ли код в вашем вопросе просто примером вашей проблемы или это реально? Другими словами, ваш код создает переменнуюsku_prod_nbr» но тогда не использует его.

Ответы на вопрос(1)

Решение Вопроса

Попробуйте использоватьPROC APPEND вместо твоегоновый» набор данных; это будет намного, намного быстрее

%macro DOIT;

proc sql noprint;
   select count(*) into : num_recs
   from datasetNames;
quit;

%do i=1 %to &num_recs;

data _null_;
  i = &i;
  set datasetNames point=i;
  call symput('ds_name',datasetname);
  stop;
run; /* UPDATE:  added this line */

%if &i = 1 %then %do;
/* Initialize MASTER with variables in the order you wish */
data master(keep=var1 var2 var3);
   retain var1 var2 var3;
   set libin.&ds_name;
   stop;
run;
%end;

proc append base=master data=libin.&ds_name(keep=var1 var2 var3);
run;

%end;

%mend DOIT;

PROC APPEND добавит каждый набор данных в ваш новыймастер" без восстановления каждый раз, как вы делаете сейчас. Это также позволяет избежать использованияCALL EXECUTEустранение проблемы с памятью, с которой вы столкнулись (вызванной генерацией большого количества кода в стеке выполнения).

 Jim Crozier18 нояб. 2012 г., 20:42
Огромное спасибо. Работал как шарм. Пришлось изменить строку набора datasetNames point = i; установить datasetNames (firstobs = &я. obs = &i); и удалил оба оператора stop, потому что они ограничивали считываемые данные, но, кроме того, это работало отлично Еще раз спасибо, это было большой помощью.
 BellevueBob18 нояб. 2012 г., 21:01
Я пропустилrun выписка из кода; увидеть обновление; это могло вызвать твою проблему.stop заявление необходимо при использованииpoint вариант в первом случае. Кроме того, если вы удалилиstop заявление от "инициализировать МАСТЕР " шаг, вы скопируете первый набор данных в MASTER. Цель состояла в том, чтобы создать пустой набор данных, поэтомуstop необходимо.
 BellevueBob18 нояб. 2012 г., 21:06
О, и я также добавилKEEP= вариант на этапе инициализации, просто чтобы четко назвать ваши переменные. И обратите внимание: этот шаг был необходим только потому, что вы попросили перечислить переменные в определенном порядке. Прочитайте документацию дляPROC APPEND Больше подробностей.

Ваш ответ на вопрос