【问题标题】:How do I read multiple excel files in SAS using a macro?如何使用宏读取 SAS 中的多个 excel 文件?
【发布时间】:2018-12-18 16:06:37
【问题描述】:

我想通过导入多个 Excel 文件在 SAS 中创建一个数据集。 excel文件内部变量相同,保存在同一目录下,文件名一致:

excel_20150101 excel_20150201

我将如何在 SAS 中编写此代码?

【问题讨论】:

    标签: macros sas


    【解决方案1】:

    此宏将遍历目录中的所有 Excel 文件,并将导入数据集中的内容,名为:DS1、DS2、DS3 ...。 DS400(如果有 400 个 Excel 文件)。请确保仅在特定目录中保留 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);     
    

    【讨论】:

    • 它们位于多个不同的 excel 工作簿而不是工作表中,我想遍历每个文件,然后创建一个数据集。这些工作表都以相同的文本开头,只是最后的日期不同。
    • 然后你可以将Excel名称作为参数传递并省略sheet =语句
    • 谢谢,如果使用上面的两个文件名,应该怎么写? SAS 新手在这里。
    • 谢谢,有没有办法写这个来循环文件而不是写出宏的最后一部分?有 400 多个文件。
    • 用日期部分写一个do循环?
    【解决方案2】:

    这里是您如何创建包含所有文件名及其路径的数据集

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

    从此列表循环通过文件表调用您的导入,就像在上面的宏中一样!

    【讨论】:

    • 请注意,根据您的操作系统,您可能需要在路径中切换 / 到 \,以上是为 UNIX 编写的
    • 谢谢两位,在 SAS 中确实需要这个,但对于 unix 也很高兴。我们不是每次都创建 400 多个数据集,而是在初始导入后每次都使用新的每日文件更新它吗?
    • 哦 SAS 在 windows 和 unix 或 linux 上运行。文件的路径 / 需要基于您的操作系统! Windows 或 Unix 上的 SAS 也是如此!它有时会帮助您了解 SAS 行为
    【解决方案3】:

    所以这会很有趣。当您从 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/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多