【发布时间】:2018-12-18 16:06:37
【问题描述】:
我想通过导入多个 Excel 文件在 SAS 中创建一个数据集。 excel文件内部变量相同,保存在同一目录下,文件名一致:
excel_20150101 excel_20150201
我将如何在 SAS 中编写此代码?
【问题讨论】:
我想通过导入多个 Excel 文件在 SAS 中创建一个数据集。 excel文件内部变量相同,保存在同一目录下,文件名一致:
excel_20150101 excel_20150201
我将如何在 SAS 中编写此代码?
【问题讨论】:
此宏将遍历目录中的所有 Excel 文件,并将导入数据集中的内容,名为:DS1、DS2、DS3 ...。 DS400(如果有 400 个 Excel 文件)。请确保仅在特定目录中保留 Excel(.xlsx) 文件。
options merror mlogic mprint symbolgen spool;
%macro drive(dir,ext);
%local filrf rc did memcnt name i;
/* Assigns a fileref to the directory and opens the directory */
%let rc=%sysfunc(filename(filrf,&dir));
%let did=%sysfunc(dopen(&filrf));
/* Loops through entire directory */
%do i = 1 %to %sysfunc(dnum(&did));
/* Retrieve name and import each Excel file */
%let name=%qsysfunc(dread(&did,&i));
proc import
out=DS&i
datafile= "Y:\Excel\&name"
dbms=XLSX replace;
getnames=yes;
run;
%end;
/* Closes the directory and clear the fileref */
%let rc=%sysfunc(dclose(&did));
%let rc=%sysfunc(filename(filrf));
%mend drive;
/* First parameter is the directory of where your files are stored. */
/* Second parameter is the extension you are looking for. */
%drive(Y:\Excel,xlsx);
【讨论】:
这里是您如何创建包含所有文件名及其路径的数据集
%let windowpath=/data/exports/Analytics/Users/psamson/Travel_project/PCA/;
data file; /*THIS PREPARE A TABLE OF TARGET FILE TO IMPORT*/
length file $200 name $28;
rc=filename("myfile","&windowpath");
DirId=dopen("myfile");
memcount=dnum(DirId);
do i = 1 to memcount;
fdir = "&windowpath./" || strip(dread(DirId,i));
rc2=filename("fdir",fdir);
fDirId=fopen("fdir");
if fDirId > 0 then do;
file = strip(dread(DirId,i));
name = substr(strip(dread(DirId,i)),1,25);
if index(file,'.xlsx') then output; /*THIS ENSURE WE ONLY IMPORT CSV file */
end;
rc2 = fclose(fDirId);
rc2= filename("fdir", "");
end;
rc = dclose(DirId);
rc = filename("myfile");
keep file name ; /*KEEP THE 2 VARIABLE TO VALIDATE AND USE FOR IMPORT*/
run;
从此列表循环通过文件表调用您的导入,就像在上面的宏中一样!
【讨论】:
所以这会很有趣。当您从 Excel 导入数据时,类型不受控制,您几乎无法控制。所以我 99% 肯定你会遇到组合数据的问题,因为类型不会对齐。我建议将所有文件转换为 CSV(通过批处理脚本),然后一次导入所有 CSV。
这是我编写的一个宏,用于导入所有内容:
%*Creates a list of all files in the DIR directory with the specified extension (EXT);
%macro list_files(dir,ext);
%local filrf rc did memcnt name i;
%let rc=%sysfunc(filename(filrf,&dir));
%let did=%sysfunc(dopen(&filrf));
%if &did eq 0 %then
%do;
%put Directory &dir cannot be open or does not exist;
%return;
%end;
%do i = 1 %to %sysfunc(dnum(&did));
%let name=%qsysfunc(dread(&did,&i));
%if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then
%do;
%put &dir\&name;
%let file_name = %qscan(&name,1,.);
%put &file_name;
data _tmp;
length dir $512 name $100;
dir=symget("dir");
name=symget("name");
path = catx('\',dir,name);
the_name = substr(name,1,find(name,'.')-1);
run;
proc append base=list data=_tmp force;
run;
quit;
proc sql;
drop table _tmp;
quit;
%end;
%else %if %qscan(&name,2,.) = %then
%do;
%list_files(&dir\&name,&ext)
%end;
%end;
%let rc=%sysfunc(dclose(&did));
%let rc=%sysfunc(filename(filrf));
%mend list_files;
%*Macro to import a single file, using the path, filename and an output dataset name must be specified;
%macro import_file(path, file_name, dataset_name );
proc import
datafile="&path.\&file_name."
dbms=xlsx
out=&dataset_name replace;
run;
%mend;
*Create the list of files, in this case all XLSX files;
%list_files(c:\_localData\temp, xlsx);
%*Call macro once for each entry in the list table created from the %list_files() macro;
data _null_;
set list;
string = catt('%import_file(', dir, ', ', name,', ', catt('test', put(_n_, z2.)), ');');
call execute (string);
run;
但是,我建议将所有文件转换为 CSV,然后再导入这些文件。 https://gist.github.com/statgeek/878e585102c14e01581f55dbe972d27e
然后将所有 CSV 一次导入到一个文件中: https://blogs.sas.com/content/sasdummy/2018/10/09/read-multiple-text-files/
【讨论】: