【问题标题】:How do I import a large csv into SAS with Variable Names intact?如何将大型 csv 导入 SAS 变量名称完整?
【发布时间】:2014-08-30 20:17:42
【问题描述】:

我正在尝试导入一个大型 CSV 文件(大约 7k 个变量和 355 个观察值)。 Proc Import 在 ~2k 列之后停止读取变量名,我不太确定为什么。我发现使用 infile 会让我将整个 csv 导入 SAS,但变量名在第一行,并且变量名为 v1-vn。我只需要从第一行中获取变量名称,然后使用它们修改/重命名我的数据集。

到目前为止,我有: 使用 infile 和 transpose 将我的所有变量名称放入单独数据集中的一列中。 使用 proc sql 将此列选择到列表中。 使用宏和此列表将我的头撞在键盘上一天半,以尝试修改原始变量名称。

我在最近(不成功)的尝试中使用了以下代码。请记住,对于大约 7k 变量,我无法手动重命名它们,甚至无法重命名其中的一小部分。我需要以某种方式使用 do 循环或宏来执行此操作,或者让 infile 正确读取变量名。

data LabImportRaw;
    length v1-v6876 $300;
    infile 'C:\xxxxxxxxxxxx\LabImportListing.csv' delimiter=',' firstobs=2 missover lrecl=250000;
    input v1-v6876 ;
run;
data LabImportVNames;
    length v1-v6876 $300;
    infile 'C:\xxxxxxxxxx\LabImportListing.csv' delimiter=',' obs=1 missover lrecl=250000;
    input v1-v6876 ;
    Array VNames(6876) v1-v6876;
run;

proc transpose
data=LabImportVNames
Out=LabImportVNames;
var v1-v6876;
run;

*Create a list of new variable names;
proc sql;
 select Col1
 into :renamelist
 from LabImportVNames;
quit;

*Create Rename Macro;
%macro rename(oldvarlist, newvarlist);
  %let k=1;
  %let old = %scan(&oldvarlist, &k);
  %let new = %scan(&newvarlist, &k);
     %do %while(("&old" NE "") & ("&new" NE ""));
      rename &old = &new;
      %let k = %eval(&k + 1);
      %let old = %scan(&oldvarlist, &k);
      %let new = %scan(&newvarlist, &k);
  %end;
%mend;

*Do the renames;
proc datasets lib=work;
modify LabImportRaw;
%rename(v1-v6786, renamelist)
run;

【问题讨论】:

    标签: csv import sas


    【解决方案1】:

    您可以使用以下方法将所有变量存储在宏变量中。您也不必指定变量的数量。 只是针对我自己的数据进行了一些定制,但它应该会给你一些线索。

    %macro simport(inname,outname);
    data vars&i;
        length v1-v10000 $10;
        infile "&inname" delimiter=',' obs=1 missover dsd lrecl=250000;
        input v1-v10000 ;
        Array VNames(10000) v1-v10000;
    run;
    
    proc transpose
    data=vars
    Out=vars;
    var v1-v10000;
    run;
    
    /* You can only extract valid variables*/
    data vars;
    set  vars;
    if col1^=' ' then output;
    run;
    
    data _null_;
    set  vars end=eof;
    call symput("var"||left(_n_),compress(COL1));
    if eof then call symput("vobs",left(_n_));
    run;
    %put &vobs;
    %put &var1;
    
    data &outname;
        infile "&inname" delimiter=',' firstobs=2 missover DSD lrecl=250000;
    %do i=1 %to &vobs;
        %let m=%sysfunc(mod((&i-1),6));
        %if &m=0 %then %do;
        informat &&var&i mmddyy10.;
        %end;
        %else %do;
        informat &&var&i best32.;
        %end;
    %end;
    %do i=1 %to &vobs;
        %let m=%sysfunc(mod((&i-1),6));
        %if &m=0 %then %do;
        format &&var&i mmddyy10.;
        %end;
        %else %do;
        format &&var&i best12.;
        %end;
    %end;
        input 
    %do i=1 %to &vobs;
            &&var&i 
    %end;
    ;
    run;
    %mend simport;
    options nomprint;
    %simport(%str(E:\Users\test\Dropbox\TradingData\Stocks\Master\CSV\STOCK1.csv),Dstocks.master1);
    

    【讨论】:

      【解决方案2】:

      我会做一些不同的事情。 开始将所有变量名称读入数据集的一个变量中:

      data LabImportVNames;
          length var $300;
          infile 'MyPath\LabImportListing.csv' delimiter=',' obs=1  lrecl=250000;
          input var @@ ;
      run;
      

      然后使用此数据集直接使用正确的变量名称编写您的输入代码(我只是采取了您的步骤并让 sas 使用 put 语句编写它),您将代码分成两部分写入外部文件,因为您需要去通过变量列表两次,第二次写入附加的文件(选项mod

      data _NULL_;
      file "MyPath\ReadCSV.sas";
      set LabImportVNames end=fine;
      if _N_=1 then do;
      put "data LabImportRaw;";
      put "    length        ";
      end;
      put "       " var       ;
      if fine then
      put "   $300;";
      run;    
      
      
      data _NULL_;
      file "MyPath\ReadCSV.sas" mod;
      set LabImportVNames end=fine;
      if  _N_=1 then do;
          put "infile 'C:\xxxxxxxxxxxx\LabImportListing.csv' delimiter=',' firstobs=2 missover lrecl=250000;";
          put "input                                                                                        ";
      end;
      put "      " var;
      if fine then do; 
          put "    ;";
          put "run;";
      end;
      run;
      

      最后包含代码:

      %include "MyPath\ReadCSV.sas";
      

      【讨论】:

        【解决方案3】:

        你在正确的轨道上,但我不会使用宏循环;只需构造一个适用于 1 个变量的重命名宏,然后调用 1000 次或其他什么。

        如果 &renamelist 适合宏变量,则以下内容将起作用;根据您的变量名,它可能不会(我什至会说可能不会)。您可以通过几种方式解决此问题;您可以将 %rename 缩短为 %r 或类似的内容(保存 5 个字符*变量数),您可以使用过滤条件创建两个或更多列表(前 1000 个、下一个 1000 等),或者不使用PROC SQL,您可以使用数据步骤并将宏调用写入临时文件,然后包含该文件。

        %macro rename(oldvar,newvar);
          rename &oldvar.=&newvar.;
        %mend rename;
        
        proc sql;
         select cats('%rename(',_name_,',',Col1,')')
          into :renamelist separated by ' '
          from LabImportVNames;
        quit;
        
        proc datasets;
         modify LabImportRaw;
         &renamelist;
        quit;
        

        【讨论】:

          猜你喜欢
          • 2011-06-26
          • 1970-01-01
          • 2019-10-31
          • 1970-01-01
          • 2016-02-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多