根据不同的标准创建变量名称的宏列表

Creating macro lists of variable names based on different criteria

我有一个非常广泛的按年龄和种族划分的人口分母数据集(针对这个问题进行了简化)如下所示:

变量名称包含每个邮政编码按种族和年龄描述的人口数量信息。所以 w_1 是 1 岁的白人,b_1 是 1 岁的黑人,a 是亚洲人,年龄从 1-100 岁。

我的任务是通过各种不同的切割方式对每个邮政编码处的人口求和。例如 5 岁以上、5-11 岁、12-17 岁、65 岁以上,按每个种族组别,按种族*年龄组别。当然,我不想为所有不同的类别输入 w_1 + w_2 + ...+ w_100。

我的策略是将相关变量名称拉入一个宏列表,用于我想要人口总和的每个类别。我已经将变量名称提取到名为“varname”的数据集中,并使用 substr() 分配变量名称 age & rage 数据,以便轻松过滤。现在我想为每个种族类型过滤那个 varname 数据集,并创建一个包含所有变量的宏列表。这是我的代码:

    %let racecat = white black aian asian nhppi latinx;
    %let race = 'W' 'B' 'I' 'A' 'P' 'H';

    %macro varlist_race;
    %let varnum= %sysfunc(countw(&racecat.));
    %do i=1 %to &varnum.;
        %let nextgroup= %scan(&racecat.,&i);

        proc sql;
            select strip(name)
            into :&nextgroup separated by ","
            from varname
            where race =%scan(&race.,&i) ;
        quit;
    %end; %mend varlist_race;
    %varlist_race;

我期望的是每个赛马的宏列表,如 &white &black 等。当我 运行 这段代码时,我的结果查看器正确打印出多个变量名称列表,但宏列表似乎没有节省。例如我后来收到这个错误。

%put &white;

WARNING: Apparent symbolic reference WHITE not resolved.

最终用法将如下所示:

    data pop2019_sums;
    set pop2019;
     pop_white = sum(white);
     pop_black = sum(&black);
     pop_asian= sum(&asian);
    run;

我不知道为什么这些宏列表在 do 循环后没有保存。非常感谢任何反馈!

宏变量有一个叫做作用域的概念。局部宏变量只存在于宏内部,一旦宏结束就不存在了。

您必须使用 %GLOBAL 语句将其显式更改为全局,以便它存在于宏之外。

%let racecat = white black aian asian nhppi latinx;
%let race = 'W' 'B' 'I' 'A' 'P' 'H';

%macro varlist_race;
%let varnum= %sysfunc(countw(&racecat.));
%do i=1 %to &varnum.;
    %global %scan(&racecat.,&i);
    %let nextgroup= %scan(&racecat.,&i);


    proc sql;
        select strip(name)
        into :&nextgroup separated by ","
        from varname
        where race =%scan(&race.,&i) ;
    quit;
%end; 
%mend varlist_race;
%varlist_race;

话虽如此,这非常繁琐且效率低下。如果您转置数据,使其结构如下:

  ZipCode  Age  Race  Count

然后,您可以使用 proc summary/means(包括任何重叠范围)以及使用多标签格式,轻松地针对不同年龄段的人群进行汇总,示例 here