Loops 动态宏变量访问SAS

Loops 动态宏变量访问SAS,loops,sas,sas-macro,Loops,Sas,Sas Macro,我使用call symputx创建了一个宏变量列表Item 1到Item N,现在我想将它们转移到另一个数据步骤中的数组中,以便数组中的点1得到Item 1,点2得到Item 2,等等 do j=1 to &num_OR; rulesUsed{j}=&&Item&j; end; 我读到双符号和语法是引用宏变量的方式,但我一直收到各种各样的错误。我相信有一个简单的方法可以解决这个问题,但我是SAS的新手,我在搜索中读过的文档中没有提到这类问

我使用call symputx创建了一个宏变量列表Item 1到Item N,现在我想将它们转移到另一个数据步骤中的数组中,以便数组中的点1得到Item 1,点2得到Item 2,等等

    do j=1 to &num_OR;
    rulesUsed{j}=&&Item&j;
    end;

我读到双符号和语法是引用宏变量的方式,但我一直收到各种各样的错误。我相信有一个简单的方法可以解决这个问题,但我是SAS的新手,我在搜索中读过的文档中没有提到这类问题

简单的回答是:一般不要这样做。宏变量不是存储数据的好方法,而且几乎总是有更好的方法

但如果需要,这里的问题是宏变量不能使用数据步长变量

 do j=1 to &num_OR;
    rulesUsed{j}=&&Item&j;
 end;
j
是一个数据步长变量,而不是宏变量,因此它不是
&j
。您需要:

1-使用
symget
检索宏变量。这是一个数据步函数,它接受一个普通的数据步字符参数(例如一个变量、一个“”字符串等),并返回具有该名称的宏变量。所以

rulesUsed[j] = symget(cats("item",j));
2-使用宏循环检索宏变量

%do j = 1 %to &num_or;
  rulesUsed[&j.] = &&item&j;
%end;

这两种方法都可以正常工作。

如果您有如下数据集:

data have ;
  ruleno+1;
  input rule $20. ;
cards;
Value1
Value2
Value3
;
您可以使用PROC转置将其转换为广域

proc transpose data=have out=want(drop=_name_) prefix=rulesUsed ;
  var rule;
  id ruleno;
run;

为什么要使用宏变量?在尝试使用宏处理器为您生成SAS代码之前,您应该先学习SAS。如果您使用了
call symputx()
,那么您必须已经在数据集中有了数据,只需再次使用该数据集即可。@Tom我需要在数据集中创建新列以应用某些规则。每次程序运行时所需的列数都会有所不同,因此需要保留一些命名约定以循环使用,这就是我尝试使用数组的原因。不知道如何将数组分配给一行的值,这就是为什么我试图列出宏变量,然后让数组引用它们--基本上,如果有5件事,我需要向数据集中添加5列,列1的值为1,列2的值为2,等等@S420L Tom的意思是,你不应该使用宏变量。数组很好——相当合理——但是宏变量不是合适的位置。使用Merge合并包含此信息的数据集,然后使用数组或其他方法。如果您想知道如何解决问题的建议,请随时提出一个更详细的问题。最好是用一个原始数据和想要的结果的例子。我不会把这个答案放在这个问题上-你可能是对的,它回答了实际的需要,但这个问题应该直接回答(为什么OP做的事情不起作用),OP应该问一个新问题来找出如何正确地做。谢谢!我现在正在尝试第二个选项,因为尽管第一个选项运行并生成一个数据集,但它不会将宏变量的值赋给数组,而是赋给作为宏变量的列的名称。我为每个宏变量(Rule1、Rule2等)保存了一列,这些宏变量由值(R1、R3、R5、R7等)组成,当我使用方法1时,结果数据集多次显示“Rule1”。这与我将&Item1分配给数组中的一个点(R1、R3等)不同。
&Item1
包含您要分配的变量名,而不是实际值?那么您可能希望使用第二个选项,是的,比使用第一个选项更简单。&Item1包含来自另一个数据集的列。由于某些原因,当使用symget时,它的计算结果是前一个变量名,我不确定第二个方法的工作原理,谢谢!对于自己是一个noob,我深表歉意,来自SQL/C/Java的SAS对我来说有点奇怪,因为在这里,东西通常一起玩得更好。