根据不同的标准创建变量名称的宏列表
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。
我有一个非常广泛的按年龄和种族划分的人口分母数据集(针对这个问题进行了简化)如下所示:
变量名称包含每个邮政编码按种族和年龄描述的人口数量信息。所以 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。