【问题标题】:SAS - append string macro variable to data set nameSAS - 将字符串宏变量附加到数据集名称
【发布时间】:2021-03-23 05:32:26
【问题描述】:

我正在尝试将字符串宏变量附加到 SAS 中的数据集名称。我想创建读取类似 work.cps2020jan 和 work.cps2020feb 的数据集。但这不是我得到的。我的代码:

%macro loop(values); 
 
     %let count=%sysfunc(countw(&values));

     %do i = 1 %to &count;                                           
      %let value=%qscan(&values,&i,%str(,));                                                                                          
      %put &value; 

    data work.cps2020&value.;
        set "A:\cpsb2020&value" ;

    mth = "&value.";

    keep
    PEMLR 
    mth
    ;

    run;

    %end;                                                                                                                      
                                                                                                                              
%mend;
                         
%loop(%str(jan,feb)); 

运行此代码会在日志中产生以下输出:

NOTE: There were 138697 observations read from the data set
      A:\cpsb2020jan.
NOTE: The data set WORK.CPS2020 has 138697 observations and 2 variables.
NOTE: The data set WORK.JAN has 138697 observations and 2 variables.
NOTE: DATA statement used (Total process time):
      real time           4.29 seconds
      cpu time            0.20 seconds


feb

NOTE: There were 139248 observations read from the data set
      A:\cpsb2020feb.
NOTE: The data set WORK.CPS2020 has 139248 observations and 2 variables.
NOTE: The data set WORK.FEB has 139248 observations and 2 variables.
NOTE: DATA statement used (Total process time):
      real time           4.44 seconds
      cpu time            0.15 seconds

我不明白为什么我的宏在每个循环中创建两个数据集,而不是在每个循环中创建一个名为 work.cps2020jan 和 work.cps2020feb 的数据集。如果我改变 &value。到&i。 SAS 输出 work.cps20201 和 work.cps20202。但这不是我想要的。

有什么见解吗?

【问题讨论】:

    标签: sas


    【解决方案1】:

    %QSCAN 宏函数将使用仅对宏处理器系统可见的特殊不可见(不可打印)字符来掩盖其结果。

    发生了什么事

    data work.cps2020&value.;
    

    被视为

    data work.cps2020<mask-character><non-masked part of symbol value><mask-character>;  
    

    在执行程序处理期间,将不可打印的掩码字符视为非语法标记分隔符,导致DATA 语句列出两个输出表。

    data work.cps2020 jan;
    

    可以使用%put _user_ 观察(在日志中)宏变量中掩码字符的位置,或者可以从元数据视图(例如SASHELP.VMACRODICTIONARY.MACRO)捕获实际符号内容

    让我们简化您的宏并添加一些日志记录和符号捕获

    %macro loop(values); 
      %local count i;
    
      %let count=%sysfunc(countw(&values));
      %do i = 1 %to &count;
        %let value=%qscan(&values,&i,%str(,));
    
        %put _user_;                   %*--- log them masks;
    
        data x&i;                      %* --- symbol capture;
          set sashelp.vmacro;
          where name like '%VALUE%';
          value_hex = put (value,$HEX40.);
        run;
    
        %* --- do the step that creates two tables;
    
        data work.cps2020&value.;
          set sashelp.class;
        run;
      %end;
    %mend;
    
    options nomprint nosymbolgen nomlogic;
    
    %loop(%str(jan,feb));
    
    proc print data=x1 noobs style(data)=[fontsize=14pt fontfamily="Courier"];
      var value:;
    run;
    

    LOG sn-p,那些小框是特殊的不可见掩码字符(我在图像捕获中显示它们,因为堆栈溢出/ html 不会显示不可打印的字符)

    相同的LOG文本,复制粘贴到Notepad2中显示掩码字符为控制字符

    捕获的宏符号数据的Proc PRINT会暴露十六进制掩码字符

    • 06 宏 %quote start
    • 08 宏 %quote end
    • 01 宏 %str 开始
    • 02 宏 %str 结束
    • 1E 逗号的掩码版本

    【讨论】:

    • 很好的解释
    • 哇——太好了,谢谢!用 scan() 替换 qscan() 后,宏做了我想做的事情(循环遍历字符串列表并将字符串附加到数据集名称)。
    【解决方案2】:

    您不需要%qscan()。如果该值包含任何需要宏引用的字符,那么无论如何它们对于在成员名称中使用都是无效的。所以请改用%scan()

    但是当在宏内部使用时,即使&amp;mvar 中没有特殊字符,标记器有时也会错误地将xxx&amp;mvar 之类的东西视为两个标记。您可以将生成的值分组以解决该问题。

    例如通过创建一个新的宏变量

    %let dsn=cps2020&value.;
    data work.&dsn. ;
    

    或者使用%unquote()函数:

    data %unquote(work.cps2020&value.);
    

    或使用名称文字:

    data work."cps2020&value."n;
    

    【讨论】:

      【解决方案3】:

      &amp;value%qscan() 引用返回。请改用%scan()。以这种方式使用带引号的宏变量有时会导致分辨率问题。最好只在需要时引用它们,例如在带有 % 符号的 %put 语句中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-21
        • 2016-07-14
        • 2013-02-09
        • 2020-11-16
        • 1970-01-01
        • 2015-08-23
        • 1970-01-01
        相关资源
        最近更新 更多