有人知道如何使用 SAS 中的 min 函数连续找到非零最小值吗?或者 SAS 代码中的任何其他选项?
当前代码:
PIP_factor = `min(PIPAllAutos, PIPNotCovByWC, PIPCovByWC, PIPNotPrincOpByEmpls);
我认为您需要使用数组解决方案,即
array pipArray pip:; *or whatever;
PIP_factor=9999;
do _n = 1 to dim(pipArray);
if pipArray[_n] > 0 then
PIP_factor = min(PIP_factor,pipArray[_n]);
end;
或者类似的。
这是另一种方法,使用 IFN 函数:
data null_;
PIPAllAutos = 2;
PIPNotCovByWC = .;
PIPCovByWC = 0;
PIPNotPrincOpByEmpls = 1;
PIP_factor = min(ifn(PIPAllAutos=0, . ,PIPAllAutos)
, ifn(PIPNotCovByWC=0, . ,PIPNotCovByWC)
, ifn(PIPCovByWC=0, . ,PIPCovByWC)
, ifn(PIPNotPrincOpByEmpls=0, . ,PIPNotPrincOpByEmpls)
);
put PIP_factor=;
run;
注意该min
函数忽略缺失值;该ifn
函数将零值设置为缺失。
可能比它的价值更多的打字; 仅作为替代方案提供。给猫剥皮的方法有很多。
/* For each row, find the variable name corresponding to the minimum value */
proc iml;
use DATASET; /* DATASET is your dataset name of interest */
read all var _NUM_ into X[colname=VarNames]; /* read in only numerical columns */
close DATASET;
idxMin = X[, >:<]; /* find columns for min of each row */
varMin = varNames[idxMin]; /* corresponding var names */
print idxMin varMin;
对于马克斯:
idxMax = X[, <:>];
我对上面的运算符不熟悉,SAS 为 IML 运算符提供了一个有用的表:
如果PROC IML
您以后需要它们,您还可以创建新数据集/将结果附加到旧数据集。
完整的博客文章:来源,所有功劳归功于 SAS 的 Rick Wicklin
编辑:对于非零部分,我会先PROC SQL
使用 aWHERE variable is not 0
进行过滤,然后再将其输入PROC IML
. 我确信它可以在 内完成PROC IML
,但我自己才开始使用它。因此,如果您知道解决方法,请发表评论PROC IML
,我将包含修复程序。
这个不受批准答案的 9999 限制。
%macro minnonzero/parmbuff;
%local _argn _args _arg;
/* get rid of external parenthesis */
%let _args=%substr(%bquote(&syspbuff),2,%length(%bquote(&syspbuff))-2);
%let _argn=1;
min(
%do %while (%length(%scan(%bquote(&_args),&_argn,%str(|))) ne 0);
%let _arg=%scan(%bquote(&_args),&_argn,%str(|));
%if &_argn>1 %then %do;
,
%end;
ifn(&_arg=0,.,&_arg)
%let _argn=%eval(&_argn+1);
%end;
);
%mend;
您使用管道分隔的参数列表调用它,例如
data piesek;
a=3;
b="kotek";
c=%minnonzero(a|findc(b,"z");
put c; /* 3, "kotek" has no "z" in it, so findc returns 0 */
run;