将 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 是更好的方法,因为调试宏很痛苦。
我需要将 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 是更好的方法,因为调试宏很痛苦。