0

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

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

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

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

尝试看起来像这样

%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;

我不认为这是可能的,但我想我会问只是为了确定。

谢谢!


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

这是一种简化问题的尝试。

实际上AAABBB是一长串单词,例如

"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,它将创建以下变量:无症状_1 暴发性_1 慢性_1 慢性_1 致命暴发_1 肝细胞_1 补偿_1 肝细胞_2 失代偿_1 致命肝细胞_1 致命肝细胞_2 致命去补偿_1

4

1 回答 1

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=germ。对于宏语言来说,右手边只是一个四字串的胚芽。它不是数据步骤变量的名称。%syfunc(cats()) 什么都不做,因为没有要连接的项目列表。

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

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

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

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

希望有帮助。

于 2016-05-31T15:50:13.927 回答