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

时间:2014-07-09 17:13:28

标签: csv import sas

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

答案 1 :(得分:0)

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

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

然后使用这个数据集直接用正确的变量名编写你的输入代码(我只是采取了你的步骤,并用s语句写了它),你将代码编写成两个部分的外部文件,因为你需要去通过变量列表两次,第二次写入您追加的文件(选项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";

答案 2 :(得分: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);