Import SAS宏循环使用proc导入读取csv文件

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

我有一个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 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*/
两个问题:

  • %2中缺少什么
  • 你看到我没有使用的更好的解决方案了吗?这些文件的结构不同,不可堆叠,只是一个提示

  • 这里输入的小错误,您需要在最后一个前面使用&而不是%

     %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导致了错误