如何让SAS识别宏变量引用,将宏变量值正确存入数据集?
问题根因
SAS宏处理器的扫描时机早于数据步执行,且DATALINES/CARDS语句块属于数据步的原始输入流,宏处理器默认不会对该块内的文本做宏解析,因此&val01.这类引用会被当做普通字符串读入数据集,不会替换为宏变量存储的实际值。另外补充一个同类型常见坑:用单引号包裹的文本内容也不会触发宏变量解析,只有双引号包裹的文本才会被宏处理器扫描。
解决方案
方法1:直接使用赋值语句构建数据集(最推荐,行数少的场景优先用)
不需要修改你之前创建宏变量的PROC SQL代码,只需要改写最终构建teste数据集的数据步即可,避免使用DATALINES块:
/* 原有创建宏变量的代码保持不变 */ PROC SQL; SELECT SUM(Invoice)/1000 FORMAT COMMAX18.2 INTO :val01 FROM SASHELP.CARS; QUIT; %PUT &val01.; PROC SQL; SELECT COUNT(Model) FORMAT COMMAX12. INTO :val02 FROM SASHELP.CARS; QUIT; %PUT &val02.; PROC SQL; SELECT SUM(MSRP)/1000000 FORMAT COMMAX18.2 INTO :val03 FROM SASHELP.CARS; QUIT; %PUT &val03.; /* 改写后的数据步 */ data WORK.teste; length col01 $10 col02 $20 col03 $2; col01='Invoice'; col02="&val01."; col03='k'; output; col01='Model'; col02="&val02."; col03='un'; output; col01='MSRP'; col02="&val03."; col03='mi'; output; run; proc print data=WORK.teste; run;
方法2:使用RESOLVE函数强制解析DATALINES内的宏引用
如果确实需要保留DATALINES逐行输入的结构,可以用RESOLVE函数对读取到的宏引用字段做强制解析:
data WORK.teste; input col01 $ col02_raw $ col03 $; col02 = resolve(col02_raw); drop col02_raw; datalines; Invoice &val01. k Model &val02. un MSRP &val03. mi ; run; proc print data=WORK.teste; run;
RESOLVE函数会在数据步运行阶段主动触发文本的宏解析操作,自动替换文本内的宏变量、宏调用为对应结果。
内容的提问来源于stack exchange,提问作者Eder Domingues
相关产品推荐
相关产品推荐

