【发布时间】:2017-01-09 19:08:19
【问题描述】:
基本上,我正在编写一个宏,它将我的输入表、输出表和变量列表作为参数。我的变量列表显示为单个参数,为此我使用空格字符作为分隔符。 我的宏应该将我的列表分成 nbvar 宏变量,这些变量将包含我的 (SAS) 变量的名称。然后我使用数据步将我的 (SAS) 变量从其原始字符格式输入到数值。
这是我的一段代码:
%macro convert_car_to_num(input,output,listvar);
/* First I split my list into nbvar variables named var&i
%qscan to avoid macro resolution of names, not really necessary here
but still works fine. My delimiter is space character, hence
%str( ) in the %qscan*/
%let nbvar=%sysfunc(countw(&listvar));
%do i = 1 %to &nbvar;
%let var&i=%qscan(&listvar,&i,%str( ));
%end;
/*Here is my data step. &&var&i_num is resolved just fine*/
data &output;
set &input;
%do i = 1 %to &nbvar;
&&var&i.._num = input(&&var&i,BEST16.);
%end;
run;
%mend;
由于 &&var&i.._num 和 &&var&i 已解决,我希望我的代码可以工作,但我的日志显示:
varname_num
180
解析的名称“varname”带有下划线。过了一会儿,我找到了:
错误 180-322:语句无效或使用顺序不正确。
这通常是分号错位的标准错误。然而,我知道我的宏变量自 mprint 显示以来已解决:
MPRINT(CONVERT_CAR_TO_NUM): varname_num = input(varname,BEST16.)
注意:由宏变量“VAR26”生成的行。
MPRINT(CONVERT_CAR_TO_NUM):运行;
其中 varname 是我列表中第 26 个变量的正确名称,这表明解析工作正常。
为了让我更难以理解,我要指出的同一段代码:
&&var&i.. = input(&&var&i,BEST16.);
可以编译,即使它最终没有达到预期的结果(变量仍然是 char)。
同样的代码:
&&var&i.._num = &&var&i;
也不编译。
我还测试了将我的宏变量的名称更改为 num_&&var&i 或 n&&var&i,甚至首先声明一个包含 &&var&i 的宏变量“名称”,所有效果都相同。不选择与初始变量相同的名称似乎会导致代码显示 180 错误。
我想问题在于尝试声明一个变量,因为我知道我之前编写的一段类似的代码确实可以工作,而 datastep 是一个比较(也将变量列表中的缺失值转换为零):
data &output;
set &input;
%do i = 1 %to &nbvar;
if &&var&i = . then &&var&i = 0;
%end;
run;
但是对于同一段代码,如果我尝试创建一个新变量(同样可以使用任何名称),请编写:
if num_&&var&i = . then &&var&i = 0;
我发现自己的解析名称再次下划线,但现在指向以下错误:
错误 22-322:语法错误,应为以下之一:!, !!, &, (, *, **, +, -, /, ;, , =, >, >=, AND, EQ, GE, GT, IN, LE, LT, MAX, MIN, NE, NG, NL, NOTIN, OR, [, ^=, {, |, ||, ~=.
【问题讨论】: