【问题标题】:SAS - read multiple CSV files and create a dataset for each one of themSAS - 读取多个 CSV 文件并为每个文件创建一个数据集
【发布时间】:2020-03-16 06:35:03
【问题描述】:

我使用此代码将 CSV 文件数据输入 SAS:

%macro drive(dir,ext); 
   %local cnt filrf rc did memcnt name; 
   %let cnt=0;          

   %let filrf=mydir;    
   %let rc=%sysfunc(filename(filrf,&dir)); 
   %let did=%sysfunc(dopen(&filrf));
   %if &did ne 0 %then %do;   
     %let memcnt=%sysfunc(dnum(&did));    

     %do i=1 %to &memcnt;              

       %let name=%qscan(%qsysfunc(dread(&did,&i)),-1,.);                    

       %if %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) %then %do;
         %if %superq(&ext) = %superq(&name) %then %do;                         
           %let cnt=%eval(&cnt+1);       
           %put %qsysfunc(dread(&did,&i));

           proc import 
             datafile="&dir\%qsysfunc(dread(&did,&i))"
             dbms=csv
             replace
             out=dsn&cnt 
           ;            
           run;         

         %end; 
       %end;      
     %end;
   %end;
   %else
     %put &dir cannot be open.;

   %if &did %then %let rc=%sysfunc(dclose(&did));      

 %mend drive;

%drive(C:path\to\folder\,csv) 

但它将数据集命名为 dsn1、dsn2 等,而我希望将文件的名称(不包括 CSV 部分)作为数据集名称。我该怎么做?

【问题讨论】:

  • 您确定文件名可以用作数据集名称吗? SAS 数据集名称限制为 32 个字符,并且必须遵循 SAS 命名规则。
  • 那段代码还能用吗?您正在使用 %superq() 函数错误。它希望引用宏变量的名称,而不是引用的值。
  • @Tom 代码最初来自这里,它确实有效documentation.sas.com/…
  • @Reeza SAS 发布了很多写得不好的代码,因为它们只是为了强调一个观点。如果您使用EXT=csv 调用该代码,那么%superq(&ext) 表达式将引用未定义的CSV 宏变量的值。

标签: sas


【解决方案1】:

我认为问题是宏调用的原因。更改文件夹以更正一个,例如:

%drive(C:\temp\,csv)

UPDATE(解决数据集命名问题):

%macro read(dir,ext);%macro d; %mend d;
filename filelist pipe "dir /b &dir*.&ext"; 

data want;
  infile filelist dlm="¬";
  length cmd_line $2000;
  input cmd_line;
run;

proc sql noprint;
   select tranwrd(cmd_line,".&ext",'') into:dataset_list separated by ' ' from want;
quit;

%do i=1 %to %sysfunc(countw(&dataset_list));
   %let dataset_name = %scan(&dataset_list,&i,%str( ));
          proc import datafile="&dir.&dataset_name..&ext" out=&dataset_name
           dbms=csv replace;            
          run;
%end;
filename filelist clear;
%mend read;

%read(c:\temp\,csv);

【讨论】:

  • 不会帮助覆盖out=dsn&cnt
  • 现在更好了!我对整个事情都使用了 call execute ,因为它更轻松。但是问题代码已经是方式了。
  • 只有在您启用了管道访问时才有效,这并不能保证。无论这些设置如何,上述程序都能正常工作。
【解决方案2】:

对于要处理使用dread 检索到的目录成员名称的内幕,而不是处理由ds&cnt 编码的第i 个处理的文件。

FIND 点 (.) 在文件名中的位置,并将名称和扩展名分开。提取文件名的名称部分后,compress 取出所有非 SAS 名称字符。

 %do i=1 %to &memcnt;              

   %let filename = %qsysfunc(dread(&did,&i));

   %let pindex = %sysfunc(FIND(&filename,.,-%length(&filename)));

   %if &pindex > 1 %then %do;
     %let extpart = %upcase(%substr(&filename,&pindex));
     %let namepart = %substr(&filename,1, &pindex);

     %* keep only characters that are valid for a sas name (normalize the namepart);
     %let sasname = %sysfunc(compress(&namepart,,kn));

     %if &extpart = CSV %then %do;

       proc import 
         datafile="&dir\&filename"
         dbms=csv
         replace
         out=work.&sasname
       ;            
       run;         

     %end;
   %end;
 %end;

如果文件名太长,生成的IMPORT 将出错。请务必与数据提供者协调,以便您获得

  • 正确的文件名,以及
  • 规范化时不冲突的文件名

【讨论】:

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