首页 文章

在call symput语句中使用动态宏变量

提问于
浏览
1

我不久前发布了一个关于修剪宏变量的问题,我用它从Yahoo Finance下载一个CSV,其中包含每个传递到站点的变量信息 . 建议我实现这一目标的代码如下:

data _null_;
a = "&testvar.";
call symputx('svar',trim(input(a,$8.)));
run;

这很有效,但是我需要重新设计代码,以便我声明多个宏变量并同时提交多个宏变量 .

要同时声明多个宏,我使用了以下代码行:

%let svar&e. = &svar.;
%put stock_ticker = &&svar&e.;

变数&e . 是一个迭代变量,每次都会增加一个 . 这声明了与名为&svar的宏看起来相同的宏 . 每次将它们放入日志中时,新的动态宏现在都会抛出以下原始警告消息:

WARNING: The quoted string currently being processed has become more than 262 characters long.  You
         may have unbalanced quotation marks.

在我开始使用我原来问题中建议的symputx选项之前,我得到了 .

下面列出了此特定嵌套宏的完整代码:

%macro symbol_var;

/*here the start row and end row created in the macro above are passed to this nested macro and then passed through the*/
/*source dataset. at the end of the loop each ticker macro variable is defined in turn for use in the following nested*/
/*macro, symbol by metric.*/

%do e = &beg_point. %to &end_point. %by 1;

%put stock row in dataset nasdaq ticker = &e.;

%global svar&e;

proc sql noprint;
select symbol
into :testvar
from nasdaq_ticker
where monotonic() = &e.;
quit;

/*convert value to string here*/

data _null_;
a = "&testvar.";
call symputx('svar',trim(input(a,$8.)));
run;

%let svar&e. = &svar.;
%put stock_ticker = &&svar&e.;


%end;
%mend;

%symbol_var;

任何人都有任何建议如何声明宏&& svar&e . 直接进入调用synputx步骤?它当前抛出一个错误,表示正在创建的宏变量不能包含任何特殊字符 . 我已经尝试使用&QUOTE,%NRQUOTE和%NRBQUOTE但是我在无效的上下文中使用了该函数,或者我没有完全正确的语法 .

谢谢

2 回答

  • 0

    尝试

    call symputx("svar&e",trim(input(a,$8.)));
    

    你需要双引号(“”)来解析e宏 .

    顺便说一句,如果$ testvar是一个字符串而不是一个数字,我不确定你是否需要输入语句 .

    我会写这个

    %macro whatever();
    proc sql noprint;
    select count(*)
    into :n
    from nasdaq_ticker;
    
    select strip(symbol) 
    into :svar1 - :svar%left(&n)
    from nasdaq_ticker;
    quit;
    
    %do i=1 %to &n;
       %put stock_ticker = &&svar&i;
    %end;
    %mend;
    
  • 0

    这不是简单的以下两行数据步骤吗?

    %macro symbol_var;
    
    /*here the start row and end row created in the macro above are passed to this nested macro and then passed through the*/
    /*source dataset. at the end of the loop each ticker macro variable is defined in turn for use in the following nested*/
    /*macro, symbol by metric.*/
    
    data _null_;
       set nasdaq_ticker(firstobs=&beg_point. obs=&end_point.);
       call symputx('svar' || strip(_n_), symbol);
    run;
    
    %mend;
    
    %symbol_var;
    

    或者以下(包括调试输出)

    %macro symbol_var;
    
    /*here the start row and end row created in the macro above are passed to this nested macro and then passed through the*/
    /*source dataset. at the end of the loop each ticker macro variable is defined in turn for use in the following nested*/
    /*macro, symbol by metric.*/
    
    data _null_;
       set nasdaq_ticker(firstobs=&beg_point. obs=&end_point.);
       length varname $ 32;
       varname = 'svar' || strip(_n_);
       call symputx(varname, symbol);
    
       put varname '= ' symbol;
    run;
    
    %mend;
    
    %symbol_var;
    

    当操纵宏变量并且需要防弹代码时,我经常发现自己恢复使用数据空步骤 . 原帖包含引用字符串警告的问题 . 发生这种情况是因为SAS宏解析器不会从语法扫描程序中隐藏宏变量的值 . 这意味着您的数据(存储在宏变量中)可能会在程序中创建语法错误,因为SAS会尝试将其解释为代码(不寒而栗!) . 它真的让我脖子后面的头发站起来冒险将我的程序放在数据中可能存在的程序中 . 使用数据步骤和功能可以完全保护您 . 您会注意到我的代码从不使用除观察窗口点之外的&符号 . 这使得我的代码可以证明nasdaq_ticker数据集中可能存在的脏数据 .

    此外,重要的是要指出Dom和我都编写了一个通过nasdaq_ticker数据集的代码 . 不打击原始发布的代码,但以这种方式循环会导致对结果集中的每个观察进行proc sql调用 . 这将为大型结果集创建非常差的性能 . 我建议您了解宏循环将导致您读取数据集的次数 . 在我自己的代码中,我被这多次咬过 .

相关问题