SAS 宏变量引号
SAS macro variable quotes
我有一个宏变量
%let data =london paris;
真正的变量是由一个sql组成的语句,并且会发生变化。我想要什么
做的是新建一个宏变量datalist,长这样:
('london' , 'paris')
我将在 where 语句中使用它(旧的是一个包含城市变量的 table):
data new;
set old;
where city in &datalist;
run;
我曾尝试用以下丑陋的方式制作这个变量:
%let data =london paris;
%let datalist = (%str(%')%sysfunc(tranwrd(&data,%str( ),%str(%' , %')))%str(%'));
%put &datalist;
但是当我 运行 这段代码时,我收到了以下错误消息:
10 %let data =london paris;
11 %let datalist = (%str(%')%sysfunc(tranwrd(&data,%str( ),%str(%' , %')))%str(%'));
NOTE: Line generated by the macro function "SYSFUNC".
1 london' , 'paris
-----
49
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS
release. Inserting white space between a quoted string and the succeeding
identifier is recommended.
12 %put &datalist;
NOTE: Line generated by the macro variable "DATALIST".
1 ('london' , 'paris')
-----
49
('london' , 'paris')
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS
release. Inserting white space between a quoted string and the succeeding
identifier is recommended.
真正奇怪的是,如果我输入一个 %unqote:
,我就可以使用这个变量
data new;
set old;
where city in %unquote(&datalist);
run;
但我仍然收到此错误消息。有没有更好的方法将数组变量从更改为:
巴黎伦敦 -> ('paris' , 'london')
解决方案
Quentin提出的简单方案居然解决了我的问题
where findw("&datalist",trim(city)) ;
但是 Quentin 提出的宏也可以找到,但由于我的变量中没有任何空格(它不是我数据集中的城市,而是 sas 列名称)这个简单的解决方案就足够了。
您的 %str
需要取消引用,其中之一。我不会使用 translate
或类似的东西;而是将其设为宏并循环遍历单词。
%let data =Jane Alfred;
%macro quote_data(var=);
%do i = 1 %to %sysfunc(countw(&var.)); %unquote(%str(%')%scan(&var.,&i.)%str(%'))
%end;
%mend quote_data;
%let dataquote = %quote_data(var=&data.);
%put &=dataquote.;
proc sql;
select * from sashelp.class
where name in (&dataquote.);
quit;
您需要将 %unquote
放在我做的地方或稍后(例如在 %let
或使用它时)。
我是 Richard DeVenezia 的 %seplist 实用程序宏的忠实粉丝:http://www.devenezia.com/downloads/sas/macros/index.php?m=seplist。我在我的个人图书馆中修改了它,使最后的声明 %unquote(&emit)
而不是 &emit
。
有了它,您可以编写代码:
where city IN (%seplist(&datalist,nest=Q)) ;
nest=Q
为列表中的每个项目添加单引号。
也就是说,另一种选择是使用 FINDW,这样您就无需对每个项目都进行引用,即:
where findw("&datalist",trim(city)) ;
使用这种基于TRANWRD()
函数的方法最大的问题是你需要确保你的space分隔列表只有一个space单词之间。但是因为你是用 PROC SQL 生成它的,所以你应该没问题。如果手动输入,则添加对 COMPBL()
的调用以清理源字符串。
您可以使用宏引号创建字符串,然后删除宏引号。
%let data =london paris;
%let qlist=%qsysfunc(tranwrd(&data,%str( ),%bquote(',')));
%let qlist=(%unquote(%bquote('&qlist')));
或者您可以使用双引号创建字符串,然后将双引号反转为单引号。
%let data =london paris;
%let qlist=("%sysfunc(tranwrd(&data,%str( ),%bquote(",")))");
%let qlist=%sysfunc(translate(&qlist,'"',"'"));
当然,如果您没有将 space 分隔版本用于其他任何内容,则只需直接在 PROC SQL 中生成引用版本。您可以稍后添加 ()
。
select quote(trim(city),"'") into :data separated by ',' ...
...
where city in (&data)
...
我有一个宏变量
%let data =london paris;
真正的变量是由一个sql组成的语句,并且会发生变化。我想要什么 做的是新建一个宏变量datalist,长这样:
('london' , 'paris')
我将在 where 语句中使用它(旧的是一个包含城市变量的 table):
data new;
set old;
where city in &datalist;
run;
我曾尝试用以下丑陋的方式制作这个变量:
%let data =london paris;
%let datalist = (%str(%')%sysfunc(tranwrd(&data,%str( ),%str(%' , %')))%str(%'));
%put &datalist;
但是当我 运行 这段代码时,我收到了以下错误消息:
10 %let data =london paris;
11 %let datalist = (%str(%')%sysfunc(tranwrd(&data,%str( ),%str(%' , %')))%str(%'));
NOTE: Line generated by the macro function "SYSFUNC".
1 london' , 'paris
-----
49
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS
release. Inserting white space between a quoted string and the succeeding
identifier is recommended.
12 %put &datalist;
NOTE: Line generated by the macro variable "DATALIST".
1 ('london' , 'paris')
-----
49
('london' , 'paris')
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS
release. Inserting white space between a quoted string and the succeeding
identifier is recommended.
真正奇怪的是,如果我输入一个 %unqote:
,我就可以使用这个变量data new;
set old;
where city in %unquote(&datalist);
run;
但我仍然收到此错误消息。有没有更好的方法将数组变量从更改为:
巴黎伦敦 -> ('paris' , 'london')
解决方案 Quentin提出的简单方案居然解决了我的问题
where findw("&datalist",trim(city)) ;
但是 Quentin 提出的宏也可以找到,但由于我的变量中没有任何空格(它不是我数据集中的城市,而是 sas 列名称)这个简单的解决方案就足够了。
您的 %str
需要取消引用,其中之一。我不会使用 translate
或类似的东西;而是将其设为宏并循环遍历单词。
%let data =Jane Alfred;
%macro quote_data(var=);
%do i = 1 %to %sysfunc(countw(&var.)); %unquote(%str(%')%scan(&var.,&i.)%str(%'))
%end;
%mend quote_data;
%let dataquote = %quote_data(var=&data.);
%put &=dataquote.;
proc sql;
select * from sashelp.class
where name in (&dataquote.);
quit;
您需要将 %unquote
放在我做的地方或稍后(例如在 %let
或使用它时)。
我是 Richard DeVenezia 的 %seplist 实用程序宏的忠实粉丝:http://www.devenezia.com/downloads/sas/macros/index.php?m=seplist。我在我的个人图书馆中修改了它,使最后的声明 %unquote(&emit)
而不是 &emit
。
有了它,您可以编写代码:
where city IN (%seplist(&datalist,nest=Q)) ;
nest=Q
为列表中的每个项目添加单引号。
也就是说,另一种选择是使用 FINDW,这样您就无需对每个项目都进行引用,即:
where findw("&datalist",trim(city)) ;
使用这种基于TRANWRD()
函数的方法最大的问题是你需要确保你的space分隔列表只有一个space单词之间。但是因为你是用 PROC SQL 生成它的,所以你应该没问题。如果手动输入,则添加对 COMPBL()
的调用以清理源字符串。
您可以使用宏引号创建字符串,然后删除宏引号。
%let data =london paris;
%let qlist=%qsysfunc(tranwrd(&data,%str( ),%bquote(',')));
%let qlist=(%unquote(%bquote('&qlist')));
或者您可以使用双引号创建字符串,然后将双引号反转为单引号。
%let data =london paris;
%let qlist=("%sysfunc(tranwrd(&data,%str( ),%bquote(",")))");
%let qlist=%sysfunc(translate(&qlist,'"',"'"));
当然,如果您没有将 space 分隔版本用于其他任何内容,则只需直接在 PROC SQL 中生成引用版本。您可以稍后添加 ()
。
select quote(trim(city),"'") into :data separated by ',' ...
...
where city in (&data)
...