SAS在行中找到非零最小值

时间:2013-09-27 19:36:44

标签: sas min

有人知道如何使用SAS中的min函数连续找到非零最小值吗?或SAS代码中的任何其他选项?

当前代码:

PIP_factor = `min(PIPAllAutos, PIPNotCovByWC, PIPCovByWC, PIPNotPrincOpByEmpls);

4 个答案:

答案 0 :(得分:2)

我认为你需要使用数组解决方案,即

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;

或者某些人。

答案 1 :(得分:1)

这是另一种使用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函数将零值设置为缺失。

可能打字比它的价值更高;仅作为替代方案提供。皮肤猫的方法有很多种。

答案 2 :(得分:0)

/* 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;

对于Max:

idxMax = X[, <:>]; 

我对上面的操作员并不熟悉,SAS为IML操作员提供了一个有用的表格:

IML Operators

PROC IML中,如果以后需要,您还可以创建新数据集/将结果附加到旧数据集中。

完整博客文章:source归功于SAS的Rick Wicklin

编辑:对于非零部分,我只需使用PROC SQL进行WHERE variable is not 0过滤,然后再将其PROC IML投放。我确信它可以在PROC IML内完成,但我刚开始自己​​使用它。所以,如果您在PROC IML中了解相关方法,请发表评论,我将包含修复方法。

答案 3 :(得分:0)

这个没有受到批准答案的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;