所以我为此创建了一个宏,但问题是我有很多变量;超过 50 个。我希望有一种有效的创建方法,这样我就可以传递新变量列表,而不必为每个变量显式调用宏
%macro cal_tot_hit(var, tot_hit);
(select sum(b.&var)
from parent_data as b
where a.ID = b.ID
and b.&var= 1) as &tot_hit
%mend;
/* call macro */
proc sql;
create table tot_hit as
select a.*,
%cal_tot_hit(var1, var1_tot_hit),
%cal_tot_hit(var2, var2_tot_hit),
%cal_tot_hit(var3, var3_tot_hit),
.......
.......
times rest of variables (n=50+ lines)
from parent_data as a
order by a.ID, a.date;
quit;
我也可以创建一个新变量数组,如下所示
proc sql noprint;
select cats(name,"_total") into :tot_vars separated by " "
from dictionary.columns
where
libname = "work" and memname = "parent_data"
and name like 'var_%';
quit;
但是我如何使用数组和 do 循环过程来随后使用每个 ID 的所需总和填充这些新的总变量,其中 ID 对每个日期都有多个观察值?
简单的答案是停止使用
PROC SQL
。其他 SAS PROC 可以更优雅地处理动态变量列表。如果你的变量都被称为 VARn
这样就可以了:
/* Assuming your input dataset is already sorted by ID. */
proc transpose data=parent_dataset out=long;
by ID;
var VAR:;
run;
data summed / view=summed;
set long;
array arr_col COL:;
/* Summing, assuming your VARs are coded 0/1 (otherwise, extend logic). */
SUM = sum(of arr_col[*]);
keep ID _NAME_ SUM;
run;
proc transpose data=summed out=wide(drop=_NAME_) suffix=_tot_hit;
by ID;
id _NAME_;
var SUM;
run;
/* Merge back into your parent dataset. */
data want;
merge parent_dataset wide;
by ID;
run;
当然,这还需要几个步骤,而且您没有 SQL 优化器的黑魔法,但这更加简洁。请注意,您不必完全明确地了解求和的变量或合并回来的变量 - 在 PROC SQL 中您必须如此。突然多了 10 倍
VARn
?只要遵循命名方案,此代码就需要零更新。即使他们不这样做,额外的一行代码也可以修复它。
如果您想更改新创建的变量的名称,同样适用 - 在这里您只需更改
suffix=
,而不是您单独输入的 50 多个值。