我编写了一个宏来proc univariate
计算数据集中变量的自定义分位数(比如dsn1
)%cust_quants(dsn= , varlist= , quant_list= )
。输出是一个汇总数据集(比如dsn2
),如下所示:
q_1 q_2.5 q_50 q_80 q_97.5 q_99 var_name
1 2.5 50 80 97.5 99 ex_var_1_100
-2 10 25 150 500 20000 ex_var_pos_skew
-20000 -500 -150 0 10 50 ex_var_neg_skew
我想做的是使用汇总数据集来限制/限制原始数据集中的极值。我的想法是提取感兴趣的列(例如q_99
)并将其放入宏变量向量中(例如q_99_1, q_99_2, ..., q_99_n
)。然后我可以执行以下操作:
/* create summary of dsn1 as above example */
%cust_quants(dsn= dsn1, varlist= ex_var_1_100 ex_var_pos_skew ex_var_neg_skew,
quant_list= 1 2.5 50 80 97.5 99);
/* cap dsn1 var's at 99th percentile */
data dsn1_cap;
set dsn1;
if ex_var_1_100 > &q_99_1 then ex_var_1_100 = &q_99_1;
if ex_var_pos_skew > &q_99_2 then ex_var_pos_skew = &q_99_2;
/* don't cap neg skew */
run;
在R
中,很容易做到这一点。可以使用像索引这样的矩阵从数据帧中提取子数据,并将该子数据分配给一个对象。然后可以稍后引用第二个对象。R
示例——b
从数据帧中提取a
:
> a <- as.data.frame(cbind(c(1,2,3), c(4,5,6)))
> print(a)
V1 V2
1 1 4
2 2 5
3 3 6
> a[, 2]
[1] 4 5 6
> b <- a[, 2]
> b[1]
[1] 4
是否可以在 SAS 中做同样的事情?我希望能够将一列子数据分配给宏变量/数组,这样我就可以在第二个数据步骤中使用宏/数组。一种想法是proc sql into:
:
proc sql noprint;
select v2 into :v2_macro separated by " "
from a;
run;
但是,当我真正想要的是变量向量(或数组——SAS 中没有向量)时,这会创建一个字符串变量。另一个想法是添加%scan
(假设这是在宏内):
proc sql noprint;
select v2 into :v2_macro separated by " "
from a;
run;
%let i = 1;
%do %until(%scan(&v2_macro, &i) = "");
%let var_&i = %scan(&v2_macro, &i);
%let &i = %eval(&i + 1);
%end;
这似乎效率低下并且需要大量代码。它还要求程序员记住哪个var_&i
对应于每个未来的目的。有没有更简单/更清洁的方法来做到这一点?
**如果这是足够的背景/示例,请在评论中告诉我。如果需要,我很乐意更完整地描述我为什么要做我正在尝试的事情。