Как мне прочитать несколько файлов Excel в SAS с помощью макроса? - PullRequest
0 голосов
/ 18 декабря 2018

Я хотел бы создать один набор данных в SAS, импортировав несколько файлов Excel.Файлы Excel имеют одинаковые переменные внутри и сохраняются в одном каталоге, все файлы имеют одинаковые имена:

excel_20150101 excel_20150201

Как мне написать это в SAS?

Ответы [ 3 ]

0 голосов
/ 19 декабря 2018

вот как вы можете создать набор данных со всеми именами файлов и их путями

%let windowpath=/data/exports/Analytics/Users/psamson/Travel_project/PCA/;

data file;  /*THIS PREPARE A TABLE OF TARGET FILE TO IMPORT*/
    length file $200 name $28;
    rc=filename("myfile","&windowpath");
    DirId=dopen("myfile");
    memcount=dnum(DirId);
    do i = 1 to memcount;
      fdir = "&windowpath./" ||  strip(dread(DirId,i));
      rc2=filename("fdir",fdir);
      fDirId=fopen("fdir");
      if fDirId > 0 then do;
        file = strip(dread(DirId,i));
        name = substr(strip(dread(DirId,i)),1,25);
        if index(file,'.xlsx') then output;  /*THIS ENSURE WE ONLY IMPORT CSV file */
      end;
      rc2 = fclose(fDirId);
      rc2= filename("fdir", "");
    end;
    rc = dclose(DirId);
    rc = filename("myfile");
    keep file name ;    /*KEEP THE 2 VARIABLE TO VALIDATE AND USE FOR IMPORT*/
run;

Из этого цикла списка через таблицу файлов вызывать импорт, как в макросе выше!

0 голосов
/ 19 декабря 2018

Так что это будет интересно.Когда вы импортируете данные из Excel, типы не контролируются, и у вас мало контроля.Так что я на 99% уверен, что вы столкнетесь с проблемой объединения данных, потому что типы не будут совпадать.Я бы порекомендовал конвертировать все ваши файлы в CSV (через пакетный скрипт), а затем импортировать все CSV одновременно.

Вот макрос, который я написал, который импортирует все:

%*Creates a list of all files in the DIR directory with the specified extension (EXT);
%macro list_files(dir,ext);
    %local filrf rc did memcnt name i;
    %let rc=%sysfunc(filename(filrf,&dir));
    %let did=%sysfunc(dopen(&filrf));

    %if &did eq 0 %then
        %do;
            %put Directory &dir cannot be open or does not exist;

            %return;
        %end;

    %do i = 1 %to %sysfunc(dnum(&did));
        %let name=%qsysfunc(dread(&did,&i));

        %if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then
            %do;
                %put &dir\&name;
                %let file_name =  %qscan(&name,1,.);
                %put &file_name;

                data _tmp;
                    length dir $512 name $100;
                    dir=symget("dir");
                    name=symget("name");
                    path = catx('\',dir,name);
                    the_name = substr(name,1,find(name,'.')-1);
                run;

                proc append base=list data=_tmp force;
                run;

                quit;

                proc sql;
                    drop table _tmp;
                quit;

            %end;
        %else %if %qscan(&name,2,.) = %then
            %do;
                %list_files(&dir\&name,&ext)
            %end;
    %end;

    %let rc=%sysfunc(dclose(&did));
    %let rc=%sysfunc(filename(filrf));
%mend list_files;

%*Macro to import a single file, using the path, filename and an output dataset name must be specified;
%macro import_file(path, file_name, dataset_name );

    proc import 
        datafile="&path.\&file_name."
        dbms=xlsx
        out=&dataset_name replace;
    run;

%mend;

*Create the list of files, in this case all XLSX files;
%list_files(c:\_localData\temp, xlsx);

%*Call macro once for each entry in the list table created from the %list_files() macro;
data _null_;
    set list;
    string = catt('%import_file(', dir, ', ',  name,', ', catt('test', put(_n_, z2.)), ');');
    call execute (string);
run;

Однако вместо этого я рекомендую преобразовать все файлы в CSV и затем импортировать их.https://gist.github.com/statgeek/878e585102c14e01581f55dbe972d27e

И затем импортировать сразу все CSV-файлы в один файл: https://blogs.sas.com/content/sasdummy/2018/10/09/read-multiple-text-files/

0 голосов
/ 18 декабря 2018

Этот макрос перебирает все файлы Excel в каталоге и импортирует содержимое в наборы данных с именами: DS1, DS2, DS3….DS400 (если есть 400 файлов Excel).Pease убедитесь, что в указанном каталоге хранятся только файлы Excel (.xlsx).

options merror mlogic mprint symbolgen spool;
%macro drive(dir,ext);                                                                                                                  
  %local filrf rc did memcnt name i;                                                                                                    

  /* Assigns a fileref to the directory and opens the directory */                                                           
  %let rc=%sysfunc(filename(filrf,&dir));                                                                                               
  %let did=%sysfunc(dopen(&filrf));                                                                                                     

   /* Loops through entire directory */                                                                                                 
   %do i = 1 %to %sysfunc(dnum(&did));                                                                                                  

     /* Retrieve name and import each Excel file */                                                                                                   
     %let name=%qsysfunc(dread(&did,&i));    
     proc import 
        out=DS&i
        datafile= "Y:\Excel\&name"
        dbms=XLSX replace;
        getnames=yes;
     run;                                                                                                                                                                                                                                                  
   %end;                                                                                                                                

  /* Closes the directory and clear the fileref */                                                                                      
  %let rc=%sysfunc(dclose(&did));                                                                                                       
  %let rc=%sysfunc(filename(filrf));                                                                                                                                                                                                                                          
%mend drive;                                                                                                                            

/* First parameter is the directory of where your files are stored. */                                                                  
/* Second parameter is the extension you are looking for.           */                                                                  
%drive(Y:\Excel,xlsx);     
...