使用&符号将变量设置为宏变量
Set variable to macro variable with ampersand
不确定如何命名这个标题,因为标题仍然很模糊,但我正在做的是。
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" 设置为变量“&var”的标签。在数据集中 "procsqldata"。因此,假设我投入过程 sql 的其中一个变量的标签是 Adam&Steve。如何在不引发错误的情况下将其设置为数据集中的变量。我试图作弊的一种方法是行不通的,因为我可能做错了
%LET steve='&steve';
但这似乎不起作用,出于某种原因它只是在数据步骤上进行了无限循环。
会有一个引用函数可以解决这个问题,但我永远记不起它们都是做什么的,为了我自己和同事的理智,我发现最好避免使用它们。
在这种情况下,您根本不需要将宏变量解析为字符串文字(即head = "&head";
);你可以使用 SYMGET
:
DATA want;
SET have;
head = SYMGET('head');
RUN;
在此处查看 SYMGET
函数的文档:
关于一个不相关的说明,您还应该阅读本页末尾的 'DICTIONARY Tables and Performance' 部分:
如果从 WHERE
子句中删除 UPCASE
函数,您的第一个查询 运行 会快多少,您可能会感到惊讶。
%SUPERQ
获取参数的名称,在宏引用的上下文中检索它的值。
如果使用的符号名称(head
)是一个具有更多上下文含义的名称(例如var_label
),您可能会有更好的长期理解。此外,您的 DICIONARY.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
&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)
宏处理器将评估宏变量 HEAD 并将该值用作您希望引用其值的宏变量的名称。而是写成:
%superq(head)
在外部使用单引号的字符串内部不计算第二个宏触发器。所以这条语句:
%let steve='&steve';
将宏变量 Steve 设置为单引号、& 符号、s、t、....单引号。
但请注意,如果您对单引号进行宏引用,那么它们就不会 属性 从宏处理器中隐藏文本。所以像这样:
%str(%')%superq(head)%str(%')
或
%bquote('%superq(head)')
将生成用引号括起来的宏变量 HEAD 的值。
所以你可能会逃脱:
head = %bquote('%superq(head)') ;
虽然有时宏引号会混淆 SAS 编译器(尤其是在宏内部),所以现在您使用单引号保护 & 符号,您可能需要删除宏引号。
head = %unquote(%bquote('%superq(head)')) ;
但真正的解决办法是完全不使用宏引用它。
要么使用 SYMGET() 函数提取值。
head = symget('head');
(确保为数据集变量 HEAD 设置长度,否则 SAS 会因为函数调用而将其默认为 $200)。
或者更好的办法是先将标签留在变量中,而不是试图通过将其塞入宏变量来混淆自己(和其他人),这样您就可以将其拉回到真正的变量中。
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;
不确定如何命名这个标题,因为标题仍然很模糊,但我正在做的是。
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" 设置为变量“&var”的标签。在数据集中 "procsqldata"。因此,假设我投入过程 sql 的其中一个变量的标签是 Adam&Steve。如何在不引发错误的情况下将其设置为数据集中的变量。我试图作弊的一种方法是行不通的,因为我可能做错了
%LET steve='&steve';
但这似乎不起作用,出于某种原因它只是在数据步骤上进行了无限循环。
会有一个引用函数可以解决这个问题,但我永远记不起它们都是做什么的,为了我自己和同事的理智,我发现最好避免使用它们。
在这种情况下,您根本不需要将宏变量解析为字符串文字(即head = "&head";
);你可以使用 SYMGET
:
DATA want;
SET have;
head = SYMGET('head');
RUN;
在此处查看 SYMGET
函数的文档:
关于一个不相关的说明,您还应该阅读本页末尾的 'DICTIONARY Tables and Performance' 部分:
如果从 WHERE
子句中删除 UPCASE
函数,您的第一个查询 运行 会快多少,您可能会感到惊讶。
%SUPERQ
获取参数的名称,在宏引用的上下文中检索它的值。
如果使用的符号名称(head
)是一个具有更多上下文含义的名称(例如var_label
),您可能会有更好的长期理解。此外,您的 DICIONARY.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
&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)
宏处理器将评估宏变量 HEAD 并将该值用作您希望引用其值的宏变量的名称。而是写成:
%superq(head)
在外部使用单引号的字符串内部不计算第二个宏触发器。所以这条语句:
%let steve='&steve';
将宏变量 Steve 设置为单引号、& 符号、s、t、....单引号。
但请注意,如果您对单引号进行宏引用,那么它们就不会 属性 从宏处理器中隐藏文本。所以像这样:
%str(%')%superq(head)%str(%')
或
%bquote('%superq(head)')
将生成用引号括起来的宏变量 HEAD 的值。
所以你可能会逃脱:
head = %bquote('%superq(head)') ;
虽然有时宏引号会混淆 SAS 编译器(尤其是在宏内部),所以现在您使用单引号保护 & 符号,您可能需要删除宏引号。
head = %unquote(%bquote('%superq(head)')) ;
但真正的解决办法是完全不使用宏引用它。
要么使用 SYMGET() 函数提取值。
head = symget('head');
(确保为数据集变量 HEAD 设置长度,否则 SAS 会因为函数调用而将其默认为 $200)。
或者更好的办法是先将标签留在变量中,而不是试图通过将其塞入宏变量来混淆自己(和其他人),这样您就可以将其拉回到真正的变量中。
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;