将 table 值设置为宏变量 SAS

Setting table value to macro variable SAS

我需要将 table 中的值存储到变量中。我试过 let、symputx 和 select。在当前版本中,我尝试使用 symputx,但未更新变量。产品 table 包含类型 price_floor、price_tier1、price_tier2。

%global price1;
%global price2;

%macro container();
DATA _null_;
    SET products;
    IF type = "Single" THEN DO;
       CALL SYMPUTX('price1', price_floor,'g');
    END;
    IF type = "Multi" THEN DO;
       CALL SYMPUTX('price1', price_tier1,'g');
       CALL SYMPUTX('price2', price_tier2,'g');
   END;
%PUT &=price1;
%PUT &=price2;
%mend;

price1 和 price2 均为 null。

SYMBOLGEN: MACRO variable PRICE1 resolves to PRICE1=
SYMBOLGEN: MACRO variable PRICE2 resolves to PRICE2=

您的数据步上没有 run 语句,因此您的 %put 语句在数据步执行之前被写入日志 - 因此,变量尚不存在.在您提供 运行 语句或步骤边界之前,它不会是 运行,或者 SAS 可能会在程序完成时礼貌地为您这样做,但无论哪种方式都不是 运行在 %put.

之前

通常这种程序是SAS中的反模式;你没有提供足够的上下文,所以也许没关系,但这只有在数据集中只有一行的情况下才有效——否则它可能不会做任何有用的事情。触发我写这篇文章的关键词是你在你的问题中称之为“变量” - 而不是“宏变量”; SAS 宏变量并不是真正的“变量”,并不意味着像 C 变量或 Python 变量那样使用。

仅供大家参考,我决定对整个程序进行重组。最初的计划是将用户定义数组的元素传递到 %container,然后使用分配的宏变量 price1 和 price2 作为另一个宏调用中的参数。

我没有将此数据步骤嵌入到宏中,而是创建了一个 table 来包含我计划传递到 %container 中的所有输入。然后我只是使用 executes 和 table 变量连接而不是直接宏调用。

data _null_;
    SET products;
    IF type = "Single" THEN DO;
       CALL execute('%split_prod('||price_floor||');');
    END;
    IF type = "Multi" THEN DO;
       CALL execute('%select_prod('||price1||','||price2||');');
    END;
run; 

除了运行之外,代码没有任何问题。

%global price1;
%global price2;

data products;
infile cards dlm=',';
input Type $ price_floor price_tier1 price_tier2;
cards;
Multi, 40, 20, 60
;;;;;


%macro container();
DATA _null_;
    SET products;
    IF type = "Single" THEN DO;
       CALL SYMPUTX('price1', price_floor,'g');
    END;
    IF type = "Multi" THEN DO;
       CALL SYMPUTX('price1', price_tier1,'g');
       CALL SYMPUTX('price2', price_tier2,'g');
   END;
RUN;

%mend;

%container();

%PUT &=price1;
%PUT &=price2;

日志:

 96         %PUT &=price1;
 PRICE1=20
 97         %PUT &=price2;
 PRICE2=60

您从未显示过对 %container() 的调用,因此不确定根本问题是什么,但 CALL EXECUTE 是更好的方法,因为调试宏很痛苦。