Sas 使用宏变量重写这些代码

Sas 使用宏变量重写这些代码,sas,Sas,a1有一个名为Qtr的列,表示今年的季度。原始代码是 %let Q1 = 0.2; %let Q2 = 0.3; %let Q3 = 0.4; %let Q4 = 0.5; 我觉得原来的那个很笨拙。如果效果是按月份而不是按季度,那么我必须编写更多的代码来进行简单的计算。所以我写了下面的代码。但它不起作用。宏变量Qtr似乎没有逐行更改 data a2; set a1; if Qtr = 1 then QtrE = &Q1; if Qtr = 2 then QtrE = &Q2;

a1
有一个名为
Qtr
的列,表示今年的季度。原始代码是

%let Q1 = 0.2;
%let Q2 = 0.3;
%let Q3 = 0.4;
%let Q4 = 0.5;
我觉得原来的那个很笨拙。如果效果是按月份而不是按季度,那么我必须编写更多的代码来进行简单的计算。所以我写了下面的代码。但它不起作用。宏变量
Qtr
似乎没有逐行更改

data a2;
set a1;
if Qtr = 1 then QtrE = &Q1;
if Qtr = 2 then QtrE = &Q2;
if Qtr = 3 then QtrE = &Q3;
if Qtr = 4 then QtrE = &Q4;
run;

data a3;
set a2;
calculated = base * QtrE;
run;

您应该阅读有关symput()如何与宏编译器和数据步骤编译器相关的文档

简而言之,您的代码无法工作,因为宏编译器解析&&&Qtr,然后将其传递给数据步骤

宏为您编写SAS代码。然后编译并运行SAS代码

这样考虑,数据步骤被编译成foreach循环

data a3;
set a1;
call symput('Qtr',cat('Q',Qtr));
calculated = base * &&&Qtr;
run;
foreach(记录在a1中):
调用symput(…);
record.calculated=record.base*;
但&qtr的值是在编写上述代码之前解析的


创建查找表可能是最好的方法。用你的值左键连接表上的值。在SAS中有许多方法可以进行左连接

您应该阅读有关symput()如何与宏编译器和数据步骤编译器相关的文档

简而言之,您的代码无法工作,因为宏编译器解析&&&Qtr,然后将其传递给数据步骤

宏为您编写SAS代码。然后编译并运行SAS代码

这样考虑,数据步骤被编译成foreach循环

data a3;
set a1;
call symput('Qtr',cat('Q',Qtr));
calculated = base * &&&Qtr;
run;
foreach(记录在a1中):
调用symput(…);
record.calculated=record.base*;
但&qtr的值是在编写上述代码之前解析的


创建查找表可能是最好的方法。用你的值左键连接表上的值。在SAS中有许多方法可以进行左连接

在这种情况下,RESOLVE应该能满足您的需求。我并不反对Dom的观点,即实际上应该创建一个查找表(在这里,格式是最好的),但具体问题是可以解决的

这仅仅是因为宏变量的值在代码中被用作一个值——也就是说,在编译步骤中它还没有定义并不重要。用于在等号左侧定义变量名的宏变量,或用作函数,或其他类似的东西,不能以这种方式使用

foreach(record in a1):
   call symput(...);
   record.calculated = record.base * <value of &qtr>;

在这种情况下,RESOLVE应该能满足您的需求。我并不反对Dom的观点,即实际上应该创建一个查找表(在这里,格式是最好的),但具体问题是可以解决的

这仅仅是因为宏变量的值在代码中被用作一个值——也就是说,在编译步骤中它还没有定义并不重要。用于在等号左侧定义变量名的宏变量,或用作函数,或其他类似的东西,不能以这种方式使用

foreach(record in a1):
   call symput(...);
   record.calculated = record.base * <value of &qtr>;

我认为DomPazz建议完全避免使用宏是最好的方法。如果由于某种原因无法执行此操作,还有一个选项是使用
symget()
函数:

%let Q1 = 0.2;
%let Q2 = 0.3;
%let Q3 = 0.4;
%let Q4 = 0.5;

data a1;
  do q=1 to 4;
    output;
  end;
run;

data a2;
  set a1;
  qtre=resolve(cats('&Q',q));
run;
据报道,symget

返回数据步骤执行期间宏变量的值


我认为DomPazz建议完全避免使用宏是最好的方法。如果由于某种原因无法执行此操作,还有一个选项是使用
symget()
函数:

%let Q1 = 0.2;
%let Q2 = 0.3;
%let Q3 = 0.4;
%let Q4 = 0.5;

data a1;
  do q=1 to 4;
    output;
  end;
run;

data a2;
  set a1;
  qtre=resolve(cats('&Q',q));
run;
据报道,symget

返回数据步骤执行期间宏变量的值


你能发布输入和输出的样本吗?你所说的“如果效果是按月而不是按季度,那么我必须写更多的代码来做简单的计算”是什么意思?你能发布示例输入和输出吗?你说的“如果效果是按月而不是按季度,那么我必须编写更多代码来进行简单计算”是什么意思?谢谢。官方支持文件非常有用。但有时我发现很难确定我应该参考支持文档的哪一部分。文档的学习曲线要比SAS的学习曲线高!谢谢官方支持文件非常有用。但有时我发现很难确定我应该参考支持文档的哪一部分。文档的学习曲线要比SAS的学习曲线高!