将表值设置为宏变量SAS



我需要将表中的值存储到变量中。我试过let, symputx和select into。在当前版本中,我尝试使用symputx,但变量没有更新。product表包含type, 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都为空。

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作为参数。

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

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; 

代码除了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是一个更好的方法,因为调试宏是痛苦的。

最新更新