Sas 使用符号AND将变量设置为宏变量

Sas 使用符号AND将变量设置为宏变量,sas,sas-macro,Sas,Sas Macro,不知道如何命名,因为标题仍然很模糊,但我正在做的是 PROC SQL NOPRINT; SELECT LABEL INTO :head FROM dictionary.columns WHERE UPCASE(MEMNAME)='PROCSQLDATA' AND UPCASE(NAME)=%UPCASE("&var."); QUIT; DATA want; SET have; head="%SUPERQ(&head.)"; RUN; 因

不知道如何命名,因为标题仍然很模糊,但我正在做的是

PROC SQL NOPRINT;
    SELECT LABEL INTO :head
    FROM dictionary.columns
    WHERE UPCASE(MEMNAME)='PROCSQLDATA' AND UPCASE(NAME)=%UPCASE("&var.");
QUIT;

DATA want;
    SET have;
    head="%SUPERQ(&head.)";
RUN;
因此,我对代码所做的是将宏变量“head”设置为数据集“procsqldata”中变量“&var.”的标签。让我们假设我在procsql中加入的一个变量的标签是Adam&Steve。如何将其设置为数据集中的变量而不引发错误。我试图欺骗的一种方法,因为我可能做错了而不起作用,那就是做错事

 %LET steve='&steve';

但这似乎不起作用,出于某种原因,它只是在数据步骤上进行无限循环

会有一个引用函数来解决这个问题,但我永远记不起它们都做了什么,我发现为了我自己和同事的理智,最好避免它们

在这种情况下,根本不需要将宏变量解析为字符串文字(即
head=“&head”
);您可以使用
SYMGET

DATA want;
  SET have;
  head = SYMGET('head');
RUN;
参见此处的
SYMGET
功能文档:

另外,您还应阅读本页末尾的“字典表和性能”部分:


如果从
WHERE
子句中删除
UPCASE
函数,您可能会惊讶于第一次查询的运行速度会快得多。

将有一个引用函数可以解决这个问题,但我永远记不起它们都做了什么,为了我自己和同事的理智,我发现最好避免它们

在这种情况下,根本不需要将宏变量解析为字符串文字(即
head=“&head”
);您可以使用
SYMGET

DATA want;
  SET have;
  head = SYMGET('head');
RUN;
参见此处的
SYMGET
功能文档:

另外,您还应阅读本页末尾的“字典表和性能”部分:


如果从
WHERE
子句中删除
UPCASE
函数,您可能会惊讶于第一次查询的运行速度会快得多。

%SUPERQ
获取参数名称,在宏引用上下文中检索参数值

如果所使用的符号名称(
head
)是一个具有更多上下文含义的名称(例如
var\u label
),您可能会有更好的长期理解。另外,您的
diciary.COLUMNS
查询应该包括
libname=
的条件。注意:LIBNAME和MEMNAME值在DICTIONARY.COLUMNS中始终为大写
Name
是列名,可以大小写混合,需要使用
upcase
来比较名称是否相等

PROC SQL NOPRINT;
    SELECT LABEL INTO :var_label
    FROM dictionary.columns
    WHERE 
       LIBNAME = 'WORK' and
       MEMNAME = 'PROCSQLDATA' and
       UPCASE(NAME)=%UPCASE("&var.")
    ;
QUIT;

data labels;
  set have;
  head_label = "%superq(var_label)";
run;
SUPERQ
参数中的
&
表示要检索其值的宏变量的名称是另一个宏变量的值

 %let p = %nrstr(Some value & That%'s that);
 %let q = p;
 %let v = %superq(&q);
 %put &=v;
 -------- LOG -------
 V=Some value & That's that
PROC SQL NOPRINT;
create table label as SELECT LABEL 
    FROM dictionary.columns
    WHERE LIBNAME='MYLIB' and MEMNAME='PROCSQLDATA' and UPCASE(NAME)=%UPCASE("&var.")
;
QUIT;

DATA want;
  SET have;
  if _n_=1 then set label;
  head = label;
  drop label;
run;
&q
成为
p
%superq
检索到的
p
值,用于分配给
v

注意:在某些情况下,可以使用
VLABEL
VLABELX
函数在运行的数据步骤中检索变量的标签

 data have;
   label weight = 'Weight (kg)';
   retain weight .;

   weight_label_way1 = vlabel ( weight );
   weight_label_way2 = vlabelx('weight');
 run;

%SUPERQ
获取参数的名称,在宏引用的上下文中检索参数的值

如果所使用的符号名称(
head
)是一个具有更多上下文含义的名称(例如
var\u label
),您可能会有更好的长期理解。另外,您的
diciary.COLUMNS
查询应该包括
libname=
的条件。注意:LIBNAME和MEMNAME值在DICTIONARY.COLUMNS中始终为大写
Name
是列名,可以大小写混合,需要使用
upcase
来比较名称是否相等

PROC SQL NOPRINT;
    SELECT LABEL INTO :var_label
    FROM dictionary.columns
    WHERE 
       LIBNAME = 'WORK' and
       MEMNAME = 'PROCSQLDATA' and
       UPCASE(NAME)=%UPCASE("&var.")
    ;
QUIT;

data labels;
  set have;
  head_label = "%superq(var_label)";
run;
SUPERQ
参数中的
&
表示要检索其值的宏变量的名称是另一个宏变量的值

 %let p = %nrstr(Some value & That%'s that);
 %let q = p;
 %let v = %superq(&q);
 %put &=v;
 -------- LOG -------
 V=Some value & That's that
PROC SQL NOPRINT;
create table label as SELECT LABEL 
    FROM dictionary.columns
    WHERE LIBNAME='MYLIB' and MEMNAME='PROCSQLDATA' and UPCASE(NAME)=%UPCASE("&var.")
;
QUIT;

DATA want;
  SET have;
  if _n_=1 then set label;
  head = label;
  drop label;
run;
&q
成为
p
%superq
检索到的
p
值,用于分配给
v

注意:在某些情况下,可以使用
VLABEL
VLABELX
函数在运行的数据步骤中检索变量的标签

 data have;
   label weight = 'Weight (kg)';
   retain weight .;

   weight_label_way1 = vlabel ( weight );
   weight_label_way2 = vlabelx('weight');
 run;
几点

首先,%SUPERQ()函数希望宏变量的名称用引号括起来。所以如果你写:

%superq(&head)
宏处理器将计算宏变量头,并使用该值作为要引用其值的宏变量的名称。相反,写为:

%superq(head)
第二个宏触发器不会在外部使用单引号的字符串内部计算。因此,这项声明:

%let steve='&steve';
将宏变量Steve设置为单引号、符号、s、t等。。。。单引号

但请注意,如果宏引用单引号,则它们不具有向宏处理器隐藏文本的属性。比如:

%str(%')%superq(head)%str(%') 

将生成包含引号的宏变量HEAD的值

因此,您可能会侥幸逃脱:

head = %bquote('%superq(head)') ;
尽管有时宏引用可能会混淆SAS编译器(尤其是宏内部),因此现在您有了单引号来保护符号,您可能需要删除宏引用

head = %unquote(%bquote('%superq(head)')) ;
但真正的解决方案是根本不使用宏引用它。

或者使用SYMGET()函数提取该值

head = symget('head');
(请确保为数据集变量HEAD设置长度,否则由于函数调用,SAS会将其默认为$200)

或者最好还是先把标签放在一个变量中,而不是把它塞进一个宏变量中,这样你就可以把它拉回到一个真正的变量中,从而混淆你自己(和其他人)

 %let p = %nrstr(Some value & That%'s that);
 %let q = p;
 %let v = %superq(&q);
 %put &=v;
 -------- LOG -------
 V=Some value & That's that
PROC SQL NOPRINT;
create table label as SELECT LABEL 
    FROM dictionary.columns
    WHERE LIBNAME='MYLIB' and MEMNAME='PROCSQLDATA' and UPCASE(NAME)=%UPCASE("&var.")
;
QUIT;

DATA want;
  SET have;
  if _n_=1 then set label;
  head = label;
  drop label;
run;
几点

首先,%SUPERQ()函数希望宏变量的名称用引号括起来。所以如果你写:

%superq(&head)
宏处理器将计算宏变量头,并使用该值作为要引用其值的宏变量的名称。而是写t