如何将宏变量值存储到 SAS 数据集中?
How can I store a macro variable value into SAS dataset?
我需要像这样在SAS数据集中存储宏变量值:
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;
input col01 $ col02 $ col03 $;
datalines;
Invoice &val01. k
Model &val02. un
MSRP &val03. mi
;
proc print data=WORK.teste;
run;
期望的结果是:
Obs col01 col02 col03
1 Invoice 12.846,29 k
2 Model 428 un
3 MSRP 14,03 mi
但是,宏变量引用并没有被SAS解释为宏变量值。
结果是:
Obs col01 col02 col03
1 Invoice &val01. k
2 Model &val02. un
3 MSRP &val03. mi
如何让 SAS 将 &val01.
理解为宏变量名,而不是字符串。
有人想要小费吗?
宏设施不接受 CARDS 或 PARMCARDS 语句。参见 https://support.sas.com/kb/43/902.html
如果你真的想这样做,这里有一些使用不同方式的例子(quote()
函数或 proc stream
):https://support.sas.com/kb/43/295.html
另一方面,使用cards
语句在宏定义中是无效的。参见
https://technologytales.com/2008/10/28/sas-macro-and-datalinecards-statements-in-data-step/
这个问题的答案来自第一个link,我复制过来写在这里:
Most of the SAS Language and all of the SAS Macro Language are 'free format' giving the ability to format and indent code for better readability. When compiling a macro, the SAS Macro Facility strips out any formatting (spaces, line breaks, tabs, etc.) in the model text to minimize the size of the stored text.
DATALINES, CARDS, and PARMCARDS statements are not free format. When the SAS Macro Facility compiles these statements, it removes the formatting, which would very possibly move data into incorrect lines and/or columns. This can cause incorrect results and is the fundamental reason for the restriction.
您可以使用 RESOLVE() 函数,只要数据行短于字符变量允许的最大长度即可。
%let val01= 12.846,29;
%let val02= 428;
%let val03= 14,03 ;
data test;
input @;
_infile_=resolve(_infile_);
input col01 $ col02 $ col03 $;
datalines;
Invoice &val01. k
Model &val02. un
MSRP &val03. mi
;
或者,如果只有 COL02 需要用宏变量的值替换,则让该列的源数据只是宏变量的名称,而不是实际的宏表达式。然后使用SYMGET()函数获取宏变量的值。
data test;
length col01-col03 ;
input col01 mvar :. col03 ;
col02 = symget(mvar);
drop mvar;
datalines;
Invoice val01 k
Model val02 un
MSRP val03 mi
;
我需要像这样在SAS数据集中存储宏变量值:
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;
input col01 $ col02 $ col03 $;
datalines;
Invoice &val01. k
Model &val02. un
MSRP &val03. mi
;
proc print data=WORK.teste;
run;
期望的结果是:
Obs col01 col02 col03
1 Invoice 12.846,29 k
2 Model 428 un
3 MSRP 14,03 mi
但是,宏变量引用并没有被SAS解释为宏变量值。
结果是:
Obs col01 col02 col03
1 Invoice &val01. k
2 Model &val02. un
3 MSRP &val03. mi
如何让 SAS 将 &val01.
理解为宏变量名,而不是字符串。
有人想要小费吗?
宏设施不接受 CARDS 或 PARMCARDS 语句。参见 https://support.sas.com/kb/43/902.html
如果你真的想这样做,这里有一些使用不同方式的例子(quote()
函数或 proc stream
):https://support.sas.com/kb/43/295.html
另一方面,使用cards
语句在宏定义中是无效的。参见
https://technologytales.com/2008/10/28/sas-macro-and-datalinecards-statements-in-data-step/
这个问题的答案来自第一个link,我复制过来写在这里:
Most of the SAS Language and all of the SAS Macro Language are 'free format' giving the ability to format and indent code for better readability. When compiling a macro, the SAS Macro Facility strips out any formatting (spaces, line breaks, tabs, etc.) in the model text to minimize the size of the stored text.
DATALINES, CARDS, and PARMCARDS statements are not free format. When the SAS Macro Facility compiles these statements, it removes the formatting, which would very possibly move data into incorrect lines and/or columns. This can cause incorrect results and is the fundamental reason for the restriction.
您可以使用 RESOLVE() 函数,只要数据行短于字符变量允许的最大长度即可。
%let val01= 12.846,29;
%let val02= 428;
%let val03= 14,03 ;
data test;
input @;
_infile_=resolve(_infile_);
input col01 $ col02 $ col03 $;
datalines;
Invoice &val01. k
Model &val02. un
MSRP &val03. mi
;
或者,如果只有 COL02 需要用宏变量的值替换,则让该列的源数据只是宏变量的名称,而不是实际的宏表达式。然后使用SYMGET()函数获取宏变量的值。
data test;
length col01-col03 ;
input col01 mvar :. col03 ;
col02 = symget(mvar);
drop mvar;
datalines;
Invoice val01 k
Model val02 un
MSRP val03 mi
;