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