首页 文章

如何将大型csv导入SAS且变量名称完好无损?

提问于
浏览
1

我正在尝试导入一个大型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;

3 回答

  • 0

    你是在正确的轨道上,但我不会使用宏循环;只需构造一个重命名宏,它可以处理1个变量并调用1000次或其他任何变量 .

    如果&renamelist适合宏变量,则以下内容将起作用;取决于你的变量名称,它可能不会(我甚至说可能不会) . 你可以通过几种方式解决这个问题;您可以缩短%重命名为%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;
    
  • 0

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

    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";
    
  • 0

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

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

相关问题