%let p1 = 1;
%let p2 = 2;
我想使用do循环创建一个数据集,其中包含p1
列中的宏变量y1
和p2
列中的宏变量y2
。
你能帮助我吗?
我尝试了以下内容:
data test;
array y(2);
do i = 1 to 2;
y(i) = &&p&i;
end;
run;
会导致以下错误:
Syntax error, expecting one of the following: a name, a quoted string,
a numeric constant, a datetime constant, a missing value, INPUT, PUT.
答案 0 :(得分:4)
您的i
是数据集变量(不是宏变量),因此&i
无法引用。
您可以将do
循环更改为宏%do
循环(并包装在宏中),因为这会创建一个宏变量或使用symget()
function来获取宏变量值基于宏变量的名称作为字符串。
宏观方法:
%macro t;
data test;
%do i = 1 %to 2;
y&i = &&p&i;
%end;
run;
%mend t;
%t;
symget
方法:
data test;
array y(2);
do i = 1 to 2;
y(i) = symget("p" || put(i, 1.));
end;
drop i;
run;
由于宏实际上是在执行数据步骤之前创建语句y# = #;
,因此数组有点多余(除非它将引用具有其他名称的变量)。我在第二个示例中添加了drop
语句,它只是从输出数据集中删除了变量i
。
编辑:讨论类型
宏变量没有类型,它们包含文本。无论您在其中存储的内容如何,SAS都会将宏变量视为相同,%let a = 1;
和%let a = Cats;
都存储文本。
通常,宏变量用于在执行之前将存储在其中的文本替换为SAS程序。在上面的第一个例子中,SAS评估宏语句并在执行数据步骤之前解析宏变量,它变为:
data test;
y1 = 1;
y2 = 2;
run;
以这种方式使用宏语言可以在您想要手动输入内容时自动编写基本SAS程序的繁琐或重复部分。考虑到这一点,请考虑您希望将字符串从宏变量传递到数据集变量的情况。
%let p1 = Canada;
上面的代码会抱怨没有名为canada
的变量,因为它会尝试解析y1 = Canada
。但是,如果您在引号中包含一个(但不是两个)作业,它将按预期工作:y&i = "&&p&i";
(或%let p1 = "Canada";
)。
symget()
将创建一个字符变量(长度$ 200。),当用于访问宏变量时,它总是返回一个字符值。
一般情况下,宏变量不是存储/移动数据的好方法,如果你有改变程序运行方式的值,它们适用于参数化脚本,但是如果要移动大量数据则可能存在更好的方法。正如Joe在上面指出的那样,可能有更好的方法来解决您的问题。