Import SAS宏循环使用proc导入读取csv文件
我有一个csv文件目录,每个文件的名称以字母m开头,以数字结尾。有十二个文件-m6到m17 我想读入它们,并将它们作为单独的数据集进行处理。我已经编写了两个宏试图这样做。Macro1有效。Macro2中断。如果我能让Macro2正常工作,我会更喜欢它,以避免不必要的部分,如创建%rawfiles、调用%sysfunc等 宏1:Import SAS宏循环使用proc导入读取csv文件,import,sas,data-cleaning,sas-macro,Import,Sas,Data Cleaning,Sas Macro,我有一个csv文件目录,每个文件的名称以字母m开头,以数字结尾。有十二个文件-m6到m17 我想读入它们,并将它们作为单独的数据集进行处理。我已经编写了两个宏试图这样做。Macro1有效。Macro2中断。如果我能让Macro2正常工作,我会更喜欢它,以避免不必要的部分,如创建%rawfiles、调用%sysfunc等 宏1: %let rawcsv = C:\ALL\dat\; %let rawfiles = m6 m7 m8 m9 m10 m11 m12 m13 m14 m15 m16 m
%let rawcsv = C:\ALL\dat\;
%let rawfiles = m6 m7 m8 m9 m10 m11 m12 m13 m14 m15 m16 m17;
%macro1;
%do i = 1 %to %sysfunc(countw(&rawfile));
%let rawfile = %scan(&rawfiles, &i);
proc import datafile="&&rawcsv.&&rawfile.csv"
out=&rawfile replace
dbms=csv;
guessingrows=500;
run;
%end;
%mend;
%macro1;
宏2:
%let rawcsv = C:\ALL\dat\;
%macro macro2(first=6, last=19);
%do i=&first. %to &last. %by 1;
proc import datafile="&&rawcsv..m&&i.csv"
out=m&i replace
dbms=csv;
guessingrows=500;
run;
%end;
%mend;
%macro2;
%macro2是我的拙劣模仿解决方案。它返回以下错误:
MPRINT(MACRO2): proc import datafile="C:\ALL\dat\m.6.csv" out=m.6 replace
dbms=csv;
MPRINT(MACRO2): ADLM;
MPRINT(MACRO2): guessingrows=500;
MPRINT(MACRO2): run;
ERROR: Library name is not assigned. /*repeats this error 14 times, once per file*/
两个问题:
这里输入的小错误,您需要在最后一个前面使用&而不是%
%do i=&first. %to %last. %by 1;
应该是:
%do i=&first. %to &last. %by 1;
除非您使用一个名为last的单独宏来确定循环的结束。但在这种情况下,您可能不会有一个名为last的参数
如果您正在寻找其他选项,我通常建议您使用数据步骤或调用EXECUTE而不是宏循环一次读取所有内容,因为在我看来,它们更容易调试
这里的小字体,您需要在最后一个前面使用&而不是%
%do i=&first. %to %last. %by 1;
应该是:
%do i=&first. %to &last. %by 1;
除非您使用一个名为last的单独宏来确定循环的结束。但在这种情况下,您可能不会有一个名为last的参数
如果您正在寻找其他选项,我通常建议您使用数据步骤或调用EXECUTE而不是宏循环一次读取所有内容,因为在我看来,它们更容易调试
从您的日志中,我们可以看到一个句点正在插入到输出数据集名称中。只需删除宏定义中的额外句点
MPRINT(MACRO2): proc import datafile="C:\ALL\dat\m.6.csv" out=m.6 replace dbms=csv;
代码中额外的&
可能会让您感到困惑。当宏处理器看到两个&
时,它会将它们转换为一个,然后重新处理字符串以进一步解析生成的宏变量引用
当宏处理器可以判断名称已结束时,不需要宏变量名称后的句点。但在某些地方需要周期。
代码中的一个位置是需要确保宏处理器知道名称的结束位置(宏变量名为readcsv
而不是readcsvm
)。另一种方法是在宏变量的值之后放置一个实际周期。您需要在此处放置两个句点,因为宏处理器在计算宏变量值时将使用第一个句点
在这个版本的macro2中,我删除了宏变量名称后面不需要句点的地方,只是为了强调需要句点的地方
%let rawcsv = C:\ALL\dat\;
%macro macro2(first, last);
%local i ;
%do i=&first %to &last ;
proc import dbms=csv
datafile="&rawcsv.m&i..csv"
out=m&i replace
;
guessingrows=500;
run;
%end;
%mend macro2;
%macro2(first=6, last=19)
从您的日志中,我们可以看到一个句点正在插入到输出数据集名称中。只需删除宏定义中的额外句点
MPRINT(MACRO2): proc import datafile="C:\ALL\dat\m.6.csv" out=m.6 replace dbms=csv;
代码中额外的&
可能会让您感到困惑。当宏处理器看到两个&
时,它会将它们转换为一个,然后重新处理字符串以进一步解析生成的宏变量引用
当宏处理器可以判断名称已结束时,不需要宏变量名称后的句点。但在某些地方需要周期。
代码中的一个位置是需要确保宏处理器知道名称的结束位置(宏变量名为readcsv
而不是readcsvm
)。另一种方法是在宏变量的值之后放置一个实际周期。您需要在此处放置两个句点,因为宏处理器在计算宏变量值时将使用第一个句点
在这个版本的macro2中,我删除了宏变量名称后面不需要句点的地方,只是为了强调需要句点的地方
%let rawcsv = C:\ALL\dat\;
%macro macro2(first, last);
%local i ;
%do i=&first %to &last ;
proc import dbms=csv
datafile="&rawcsv.m&i..csv"
out=m&i replace
;
guessingrows=500;
run;
%end;
%mend macro2;
%macro2(first=6, last=19)
在启用MPRINT选项的情况下运行第二个宏,并从生成错误的循环之一发布日志<代码>选项mprint代码>供参考-如果使用PROC导入,它将猜测类型。如果您需要组合这些文件或处理它们,您将无法假设所有变量都是以相同的数据类型读入的,因此您必须进行额外的检查或将其考虑到您的处理中。如果这只是一次,那就太乏味了,如果这需要定期运行,那肯定需要做更多的工作。它在代码中最后一个宏变量前面-,而不是%<代码>%DoI=&第一个%到%last应该是&last,而不是%last。为什么两个程序中都有这么多
&
?您似乎试图引用名为rawcvs
的宏变量。该宏变量包含什么?&&是指引号中的宏变量,但我最初没有包含&rawcvs内容。我刚刚更新了post-谢谢。使用MPRINT选项运行第二个宏,并从生成错误的循环之一发布日志<代码>选项mprint代码>供参考-如果使用PROC导入,它将猜测类型。如果您需要组合这些文件或处理它们,您将无法假设所有变量都是以相同的数据类型读入的,因此您必须进行额外的检查或将其考虑到您的处理中。如果这只是一次,那就太乏味了,如果这需要定期运行,那肯定需要做更多的工作。它在代码中最后一个宏变量前面-,而不是%<代码>%DoI=&第一个%到%last应该是&last,而不是%last。为什么两个程序中都有这么多&
?您似乎试图引用名为rawcvs
的宏变量。该宏变量包含什么?&&是指引号中的宏变量,但我最初没有包含&rawcvs内容。我刚刚更新了帖子-谢谢。捕捉得好-宏仍然没有解析,所以我已经更新了代码和错误。MPRINT导致了错误