将导入的文件名捕获到 SAS 中的变量中
Capture imported file name into a variable in SAS
我正在尝试找到一种方法,将我在 SAS 中导入的文件名称捕获到变量中,因为我想用它来构建导出文件的名称。例如,我在目录 c:\TEMP 中有文件 TEST.xlsx,我想将其导入 SAS 并在对数据进行一些操作后将结果导出为 TEST-01.xlsx。有人可以帮我做吗?
谢谢,
旦
PROC IMPORT DATAFILE= "c:\TEMP\*.xlsx" DBMS=xlsx out=TABLE_START REPLACE;
RUN;
我不知道您可以在 PROC IMPORT 中使用通配符。据我所知,在使用这种导入数据的方法时,没有一种简单的方法来捕获该信息。通配符通常用在 INFILE 语句中,而您正试图一次读取多个文件。如果文件夹中有多个 XLSX 文件,我也不知道它会读取哪个,我认为它似乎是第一个。不幸的是,XLSX 也没有向日志中添加任何更多信息。
我认为这意味着您需要完全改变您的方法。如果您以后需要文件名,我会推荐这种方法:
%let myfile = 'path to your excel file';
proc import out=want datafile=&myFile. dbms=xlsx replace; run;
data want2;
set want;
source = &myfile;
run;
如果这不是 Excel 文件,还有其他选项,但遗憾的是它是 XLSX。例如,如果您要导入多个 CSV 文件,则有 FILEVAR 和 FILENAME 选项。
如果它在日志中,您可以通过迂回的方式捕获它,但这似乎也不起作用。这对我来说有点奇怪,所以我将在 communities.sas.com 上重新发布它以查看 SAS 或其他高级用户是否有建议。
先找到名字就可以了
data _null_;
length fname 0 ;
infile "c:\TEMP\*.xlsx" filename=fname;
input @;
call symputx('fname',fname);
stop;
run;
然后您可以在导入或其他步骤中使用文件名。
PROC IMPORT DATAFILE= "&fname" DBMS=xlsx out=TABLE_START REPLACE;
RUN;
OP 不清楚是否必须处理一个或多个 Excel 文件。
回答这个问题的另一种方法是通过在 FILENAME
语句中使用 PIPE
选项来引用该文件,以通过管道传输操作系统命令的结果,例如 ls
在 Linux 或 dir
中 Windows。
如果有多个文件与 OP 中列出的通配符匹配,并且必须处理每个文件,则必须使用一种将多个文件名分配给 SAS 宏变量的技术。
作为示例数据,我将使用来自 Alberto Barradas 的 Kaggle Pokémon with Stats 数据库的 Excel 版本的数据。我将包含第 1 代、第 2 代和所有神奇宝贝的三个 Excel 文件保存到 Windows-based 计算机上的子目录中。
要导入文件集,我们首先生成文件名列表,然后将其读入 SAS 数据集中。
%let dirname = /folders/myshortcuts/sf_gitrepos/pokemonData;
filename DIRLIST pipe "dir /B &dirname\*.xlsx";
data dirlist;
length fname 6;
infile dirlist length = reclen;
input fname $varying256. reclen;
run;
请注意,如果您的 SAS 安装处于 LOCKDOWN
模式,则它无法发出操作系统命令。在这种情况下,您必须转到操作系统并发出命令以生成目录列表并将其保存到文件中。在 Windows 中它看起来像:
dir /b *.xlsx > excelfiles.txt
请注意,/b
选项表示 "bare",并打印不带摘要信息的目录列表。由于我使用 SAS University 版本来回答这个问题,因此我不得不使用以下代码将文件名读入 SAS。
data dirlist;
length fname 6;
infile "/folders/myshortcuts/sf_gitrepos/pokemonData/excelfiles.txt" length=reclen;
input fname $varying256. reclen;
run;
SAS 日志的输出:
1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
72
73 data dirlist;
74 length fname 6;
75 infile "/folders/myshortcuts/sf_gitrepos/pokemonData/excelfiles.txt" length=reclen;
76 input fname $varying256. reclen;
77 run;
NOTE: The infile "/folders/myshortcuts/sf_gitrepos/pokemonData/excelfiles.txt" is:
Filename=/folders/myshortcuts/sf_gitrepos/pokemonData/excelfiles.txt,
Owner Name=root,Group Name=vboxsf,
Access Permission=-rwxrwx---,
Last Modified=20May2018:03:56:41,
File Size (bytes)=38
NOTE: 3 records were read from the infile "/folders/myshortcuts/sf_gitrepos/pokemonData/excelfiles.txt".
The minimum record length was 10.
The maximum record length was 12.
NOTE: The data set WORK.DIRLIST has 3 observations and 1 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
接下来,我们将使用 PROC SQL 的 INTO
功能为每个文件名生成一个 SAS 宏变量,如 William Murphy 的 Changing Data Set Variables to Macro Variables 2007 SAS Users 文章中所述会议。
proc sql noprint;
select count(*) into :NObs from dirlist;
select fname into :Name1-:Name%left(&NObs) from dirlist;
run;
...以及 SAS 日志的输出:
1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
72
73 proc sql;
74 select count(*) into :NObs from dirlist;
75 select fname into :Name1-:Name%left(&NObs) from dirlist;
MPRINT(LEFT): Name3
76 run;
NOTE: PROC SQL statements are executed immediately; The RUN statement has no effect.
77
78 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
91
最后,我们将编写并执行一个 SAS 宏来迭代 运行 PROC IMPORT
以导入 Excel 文件。
%macro genimport;
%local i;
%do i = 1 %to &NObs;
proc import out=want&i datafile="&dirname/&&Name&i" dbms=xlsx replace;
run;
%end;
%mend;
%genimport;
...以及输出:
1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
72
73 %macro genimport;
74 %local i;
75 %do i = 1 %to &NObs;
76 proc import out=want&i datafile="&dirname/&&Name&i" dbms=xlsx replace;
77 run;
78 %end;
79 %mend;
80 %genimport;
MPRINT(GENIMPORT): proc import out=want1 datafile="/folders/myshortcuts/sf_gitrepos/pokemonData/gen01.xlsx" dbms=xlsx replace;
MPRINT(GENIMPORT): RXLX;
MPRINT(GENIMPORT): run;
NOTE: One or more variables were converted because the data type is not supported by the V9 engine. For more details, run with
options MSGLEVEL=I.
NOTE: The import data set has 165 observations and 13 variables.
NOTE: WORK.WANT1 data set was successfully created.
NOTE: PROCEDURE IMPORT used (Total process time):
real time 0.06 seconds
cpu time 0.03 seconds
MPRINT(GENIMPORT): proc import out=want2 datafile="/folders/myshortcuts/sf_gitrepos/pokemonData/gen02.xlsx" dbms=xlsx replace;
MPRINT(GENIMPORT): RXLX;
MPRINT(GENIMPORT): run;
NOTE: One or more variables were converted because the data type is not supported by the V9 engine. For more details, run with
options MSGLEVEL=I.
NOTE: The import data set has 106 observations and 13 variables.
NOTE: WORK.WANT2 data set was successfully created.
NOTE: PROCEDURE IMPORT used (Total process time):
real time 0.05 seconds
cpu time 0.04 seconds
MPRINT(GENIMPORT): proc import out=want3 datafile="/folders/myshortcuts/sf_gitrepos/pokemonData/Pokemon.xlsx" dbms=xlsx replace;
MPRINT(GENIMPORT): RXLX;
MPRINT(GENIMPORT): run;
NOTE: One or more variables were converted because the data type is not supported by the V9 engine. For more details, run with
options MSGLEVEL=I.
NOTE: The import data set has 800 observations and 13 variables.
NOTE: WORK.WANT3 data set was successfully created.
NOTE: PROCEDURE IMPORT used (Total process time):
real time 0.16 seconds
cpu time 0.13 seconds
为确认我们已将文件读入 SAS,我们可以在 SAS Studio 输出数据查看器中查看生成的 SAS 数据集之一。
此时,宏变量 &Name1
等可以用 %scan()
解析以获得文件名,一旦它们通过 DATA
步骤。
我正在尝试找到一种方法,将我在 SAS 中导入的文件名称捕获到变量中,因为我想用它来构建导出文件的名称。例如,我在目录 c:\TEMP 中有文件 TEST.xlsx,我想将其导入 SAS 并在对数据进行一些操作后将结果导出为 TEST-01.xlsx。有人可以帮我做吗?
谢谢, 旦
PROC IMPORT DATAFILE= "c:\TEMP\*.xlsx" DBMS=xlsx out=TABLE_START REPLACE;
RUN;
我不知道您可以在 PROC IMPORT 中使用通配符。据我所知,在使用这种导入数据的方法时,没有一种简单的方法来捕获该信息。通配符通常用在 INFILE 语句中,而您正试图一次读取多个文件。如果文件夹中有多个 XLSX 文件,我也不知道它会读取哪个,我认为它似乎是第一个。不幸的是,XLSX 也没有向日志中添加任何更多信息。
我认为这意味着您需要完全改变您的方法。如果您以后需要文件名,我会推荐这种方法:
%let myfile = 'path to your excel file';
proc import out=want datafile=&myFile. dbms=xlsx replace; run;
data want2;
set want;
source = &myfile;
run;
如果这不是 Excel 文件,还有其他选项,但遗憾的是它是 XLSX。例如,如果您要导入多个 CSV 文件,则有 FILEVAR 和 FILENAME 选项。
如果它在日志中,您可以通过迂回的方式捕获它,但这似乎也不起作用。这对我来说有点奇怪,所以我将在 communities.sas.com 上重新发布它以查看 SAS 或其他高级用户是否有建议。
先找到名字就可以了
data _null_;
length fname 0 ;
infile "c:\TEMP\*.xlsx" filename=fname;
input @;
call symputx('fname',fname);
stop;
run;
然后您可以在导入或其他步骤中使用文件名。
PROC IMPORT DATAFILE= "&fname" DBMS=xlsx out=TABLE_START REPLACE;
RUN;
OP 不清楚是否必须处理一个或多个 Excel 文件。
回答这个问题的另一种方法是通过在 FILENAME
语句中使用 PIPE
选项来引用该文件,以通过管道传输操作系统命令的结果,例如 ls
在 Linux 或 dir
中 Windows。
如果有多个文件与 OP 中列出的通配符匹配,并且必须处理每个文件,则必须使用一种将多个文件名分配给 SAS 宏变量的技术。
作为示例数据,我将使用来自 Alberto Barradas 的 Kaggle Pokémon with Stats 数据库的 Excel 版本的数据。我将包含第 1 代、第 2 代和所有神奇宝贝的三个 Excel 文件保存到 Windows-based 计算机上的子目录中。
要导入文件集,我们首先生成文件名列表,然后将其读入 SAS 数据集中。
%let dirname = /folders/myshortcuts/sf_gitrepos/pokemonData;
filename DIRLIST pipe "dir /B &dirname\*.xlsx";
data dirlist;
length fname 6;
infile dirlist length = reclen;
input fname $varying256. reclen;
run;
请注意,如果您的 SAS 安装处于 LOCKDOWN
模式,则它无法发出操作系统命令。在这种情况下,您必须转到操作系统并发出命令以生成目录列表并将其保存到文件中。在 Windows 中它看起来像:
dir /b *.xlsx > excelfiles.txt
请注意,/b
选项表示 "bare",并打印不带摘要信息的目录列表。由于我使用 SAS University 版本来回答这个问题,因此我不得不使用以下代码将文件名读入 SAS。
data dirlist;
length fname 6;
infile "/folders/myshortcuts/sf_gitrepos/pokemonData/excelfiles.txt" length=reclen;
input fname $varying256. reclen;
run;
SAS 日志的输出:
1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
72
73 data dirlist;
74 length fname 6;
75 infile "/folders/myshortcuts/sf_gitrepos/pokemonData/excelfiles.txt" length=reclen;
76 input fname $varying256. reclen;
77 run;
NOTE: The infile "/folders/myshortcuts/sf_gitrepos/pokemonData/excelfiles.txt" is:
Filename=/folders/myshortcuts/sf_gitrepos/pokemonData/excelfiles.txt,
Owner Name=root,Group Name=vboxsf,
Access Permission=-rwxrwx---,
Last Modified=20May2018:03:56:41,
File Size (bytes)=38
NOTE: 3 records were read from the infile "/folders/myshortcuts/sf_gitrepos/pokemonData/excelfiles.txt".
The minimum record length was 10.
The maximum record length was 12.
NOTE: The data set WORK.DIRLIST has 3 observations and 1 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
接下来,我们将使用 PROC SQL 的 INTO
功能为每个文件名生成一个 SAS 宏变量,如 William Murphy 的 Changing Data Set Variables to Macro Variables 2007 SAS Users 文章中所述会议。
proc sql noprint;
select count(*) into :NObs from dirlist;
select fname into :Name1-:Name%left(&NObs) from dirlist;
run;
...以及 SAS 日志的输出:
1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
72
73 proc sql;
74 select count(*) into :NObs from dirlist;
75 select fname into :Name1-:Name%left(&NObs) from dirlist;
MPRINT(LEFT): Name3
76 run;
NOTE: PROC SQL statements are executed immediately; The RUN statement has no effect.
77
78 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
91
最后,我们将编写并执行一个 SAS 宏来迭代 运行 PROC IMPORT
以导入 Excel 文件。
%macro genimport;
%local i;
%do i = 1 %to &NObs;
proc import out=want&i datafile="&dirname/&&Name&i" dbms=xlsx replace;
run;
%end;
%mend;
%genimport;
...以及输出:
1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
72
73 %macro genimport;
74 %local i;
75 %do i = 1 %to &NObs;
76 proc import out=want&i datafile="&dirname/&&Name&i" dbms=xlsx replace;
77 run;
78 %end;
79 %mend;
80 %genimport;
MPRINT(GENIMPORT): proc import out=want1 datafile="/folders/myshortcuts/sf_gitrepos/pokemonData/gen01.xlsx" dbms=xlsx replace;
MPRINT(GENIMPORT): RXLX;
MPRINT(GENIMPORT): run;
NOTE: One or more variables were converted because the data type is not supported by the V9 engine. For more details, run with
options MSGLEVEL=I.
NOTE: The import data set has 165 observations and 13 variables.
NOTE: WORK.WANT1 data set was successfully created.
NOTE: PROCEDURE IMPORT used (Total process time):
real time 0.06 seconds
cpu time 0.03 seconds
MPRINT(GENIMPORT): proc import out=want2 datafile="/folders/myshortcuts/sf_gitrepos/pokemonData/gen02.xlsx" dbms=xlsx replace;
MPRINT(GENIMPORT): RXLX;
MPRINT(GENIMPORT): run;
NOTE: One or more variables were converted because the data type is not supported by the V9 engine. For more details, run with
options MSGLEVEL=I.
NOTE: The import data set has 106 observations and 13 variables.
NOTE: WORK.WANT2 data set was successfully created.
NOTE: PROCEDURE IMPORT used (Total process time):
real time 0.05 seconds
cpu time 0.04 seconds
MPRINT(GENIMPORT): proc import out=want3 datafile="/folders/myshortcuts/sf_gitrepos/pokemonData/Pokemon.xlsx" dbms=xlsx replace;
MPRINT(GENIMPORT): RXLX;
MPRINT(GENIMPORT): run;
NOTE: One or more variables were converted because the data type is not supported by the V9 engine. For more details, run with
options MSGLEVEL=I.
NOTE: The import data set has 800 observations and 13 variables.
NOTE: WORK.WANT3 data set was successfully created.
NOTE: PROCEDURE IMPORT used (Total process time):
real time 0.16 seconds
cpu time 0.13 seconds
为确认我们已将文件读入 SAS,我们可以在 SAS Studio 输出数据查看器中查看生成的 SAS 数据集之一。
此时,宏变量 &Name1
等可以用 %scan()
解析以获得文件名,一旦它们通过 DATA
步骤。