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)
...