使用变量作为宏变量数据步骤

时间:2016-05-30 14:28:20

标签: sas datastep

我正在寻找一种在数据步骤中使用普通变量值作为宏变量的方法。

例如,我有宏变量& statesList_Syphilis = AAA
和另一个宏变量& statesList_Giardia = BBB

在数据步骤中,我有一个变量 Germ ,它包含2行:“Syphilis”和“Giardia”。

在我的数据步骤中,当Germ =“Syphilis”时,我需要在迭代第一行时找到 AAA 当迭代第二行时, BBB ,当Germ =“Giardia”时

尝试看起来像这样

%let statesList_Syphilis = AAA;
%let statesList_Giardia = BBB;

data test;
    set mytablewithgerms; * contains variable Germ ;

    * use germ and store it in &germ macro variable ;
    * something like  %let germ = germ; or call symput ('germ',germ);

    * I want to be able to do this;
    xxx = "&&statesList_&germ"; * would give xxx = "AAA" or xxx = "BBB";

    * or this;
    &&statesList_&germ = "test"; * would give AAA = "test" or BBB = "test";

    run;

我不认为这是可能的,但我想我会要求确定。

谢谢!

编辑(评论中的问题,我正在为我的具体问题添加上下文,但我觉得这会使事情变得更复杂):

这是为了简化问题。

实际上, AAA BBB 是很长的单词列表 喜欢

"asymptomatic_1 fulminant_1 chronic_1 chronic_1 fatalFulminant_1 hepatocellular_1 compensated_1 hepatocellular_2 decompensated_1 fatalHepatocellular_1 fatalHepatocellular_2 fatalDecompensated_1"

我不想将这个长字符串存储在变量中,我想在do循环中迭代这个字符串的每个单词,例如:

    %do k=1 %to %sysfunc(countw(&&statesList_&germ));
        %let state = %scan(&&statesList_&germ, &k);
        * some other code here ;
    %end;

EDIT2:
这是对我的问题的更完整的看法:

%macro dummy();

data DALY1;
    * set lengths ;
    length Germ $10 Category1 $50 Category2 $50 AgeGroupDALY $10 Gender $2 value 8 stateList$999;

    * make link to hash table ;
    if _n_=1 then do;

        *modelvalues ----------------;
        declare hash h1(dataset:'modelData');
        h1.definekey ('Germ', 'Category1', 'Category2', 'AgeGroupDALY', 'Gender') ;
        h1.definedata('Value');
        h1.definedone();
        call missing(Germ, Value, Category1, Category2);
        * e.g.
          rc=h1.find(KEY:Germ, KEY:"ssssssssss", KEY:"ppppppppppp", KEY:AgeGroupDALY, KEY:Gender);

        *states ---------------------;
        declare hash h2(dataset:'states');
        h2.definekey ('Germ') ;
        h2.definedata('stateList');
        h2.definedone();

    end;

    set DALY_agregate;

    put "°°°°° _n_=" _n_;

    DALY=0; * addition of terms ;



    rc2=h2.find(KEY:Germ); * this creates the variable statesList;

    put "statesList =" statesList;

    * here i need statesList as a macro variable,;

    %do k=1 %to %sysfunc(countw(&statesList)); *e.g. acute_1 asymptomatic_1 ...;
        %let state = %scan(&statesList, &k);
        put "=== &k &state";
        &state = 1; * multiplication of terms ;

        * more code here;
    %end;


run;
%mend dummy;
%dummy;

EDIT3:
输入数据集如下所示

Germ    AgeGroup1 AgeGroup2 Gender Cases    Year
V_HBV   15-19   15-19   M   12  2015
V_HBV   15-19   15-19   M   8   2016
V_HBV   20-24   20-24   F   37  2011
V_HBV   20-24   20-24   F   46  2012
V_HBV   20-24   20-24   F   66  2013

输出数据集将添加由宏变量定义的字符串中包含的变量,该变量取决于Germ。

例如对于V_HBV,它将创建以下变量:asymptomatic_1 fulminant_1 chronic_1 chronic_1 fatalFulminant_1 hepatocellular_1 compensated_1 hepatocellular_2 decompensated_1 fatalHepatocellular_1 fatalHepatocellular_2 fatalDecompensated_1

1 个答案:

答案 0 :(得分:0)

我没有关注大局,但是你问题的前一次迭代之一有一些代码(伪代码),它说明了宏语言如何工作的可能混淆。考虑这一步:

data _null_;
  germ="Syph";  
  call symput('germ',germ);
  %let Germ=%sysfunc(cats(germ));
  put "germ = &germ";
run;
%put &germ;

执行新SAS会话中的日志显示:

1    data _null_;
2      germ="Syph";
3      call symput('germ',germ);
4      %let Germ=%sysfunc(cats(germ));
5      put "germ = &germ";
6    run;

germ = germ

7    %put &germ;
Syph

现在让我们谈谈发生了什么。我将使用日志中的行号。

第2行将文本字符串Syph分配给数据步变量germ。没什么特别的。

第3行创建一个名为Germ的宏变量,并分配datastep变量germ的值。所以它赋予它Syph的价值。执行数据步骤时执行此CALL SYMPUT语句。

第4行是一个宏%let语句。它创建一个名为Germ的宏变量,并为其赋值germ。因为这是一个宏语句,所以它在任何DATA STEP代码执行之前执行。它不知道数据步骤变量。第4行相当于%let Germ =胚芽。对于宏语言,右侧只是一个四字符串的细菌。它不是数据步变量的名称。 %syfunc(cats())什么都不做,因为没有要连接的项目列表。

第5行是数据步骤PUT语句。在编译数据步骤时解析宏参考和细菌。此时宏变量germ解析为Germ,因为%LET语句已执行(CALL SYMPUT语句尚未执行)。

第7行是%PUT语句,它在DATA NULL 步骤完成后执行(并且在CALL SYMPUT将值Syph写入宏变量Germ之后)。

作为一般原则,难以(并且不常见)有一个数据步骤,您使用数据创建宏变量(例如通过调用symput)并在同一步骤中使用该宏变量(即引用宏变量)。在执行任何数据步骤代码之前解析宏引用。

通常,如果您的数据已经在数据集中,您可以通过数据步骤语句(DO循环而不是%DO循环等)获得所需的数据。或者,您可以使用一个DATA步骤生成宏变量,第二个DATA步骤可以引用它们。

希望有所帮助。