SAS计算百分位数并保存到宏变量

SAS Calculate percentiles and save to macro variable

我有以下代码来计算百分位数。

proc univariate data=sashelp.cars;
  var Horsepower 
  output pctlpre=P_ pctlpts= 50, 75 to 100 by 5;
run;

我想即时将这些百分位数分配给一个宏变量(因此每个百分位数 1 个宏变量)。有什么聪明的方法可以做到这一点吗?

可能不太聪明,但我认为会起作用。

proc univariate data=sashelp.cars;
  var Horsepower;
  output out=table pctlpre=P_ pctlpts= 50, 75 to 100 by 5;
run;

proc sql noprint;
   select 'call symput('|| "'" ||strip(name)||"'," || strip(name) || ");"  
   into:name_list separated by ' ' 
   from dictionary.columns 
   where libname ="WORK" and memname="TABLE";
quit;

data _null_;
   set table;
   &name_list;
run;

%put _ALL_;

Proc sql 即时生成代码:call symput('P_50',P_50); call symput('P_75',P_75); call symput('P_80',P_80); call symput('P_85',P_85); call symput('P_90',P_90); call symput('P_95',P_95); call symput('P_100',P_100);

输出:

GLOBAL P_100 500

GLOBAL P_50 210

GLOBAL P_75 255

GLOBAL P_80 275

GLOBAL P_85 295

GLOBAL P_90 302

GLOBAL P_95 340

"smart way to do this"是什么意思?你会如何处理你所说的宏?

proc univariate data=sashelp.cars noprint;
   var Horsepower;
   output pctlpre=P_ pctlpts= 50, 75 to 100 by 5;
   run;
proc print;
   run;
data _null_;
   set;
   array P_ P_:;
   do over p_;
      call symputx(vname(p_),p_);
      end;
   stop;
   run;
%put _user_;

根据 OP 关于他们真正在做什么的输入,没有必要将数据放入宏变量中。我认为当宏变量将用于计算时,永远不要 "smart" 将数据放入宏变量中。

这将创建新变量 CAP_:上限为 &p。

%let p=90;
ods select none;
ods output summary=ptile;
proc means data=sashelp.cars stackods p&P.;
   run;
ods output close;
ods select all;
proc print;
   run;
/*Flip the rows into 1 obs.  Vars with prefix P&P._*/
proc transpose data=ptile out=ptile2(drop=_:) prefix=P&P._;
   var P&P.;
   id variable;
   run;
/*Flip the rows to create new CAP_ variables.  Just for the names*/
proc transpose data=ptile out=cap(drop=_:) prefix=Cap_;
   var P&P.;
   id variable;
   run;
/*create capped variables*/
data capped;
   set sashelp.cars;
   array _v _numeric_;
   /*Create array of new variables CAP_*/
   if 0 then set cap; 
   array _cap cap_:;
   call missing(of _cap[*]);
   /*Create array of Ptile variables*/
   if _n_ eq 1 then set ptile2;
   array _tile P&P._:; 
   *drop P&P._:;
   do over _v;
      _cap = min(_tile,_v);
      end;
   run;
proc print;
   run;

这是一种仅使用一个 proc sql:

的方法
proc univariate noprint data=sashelp.class;
  var height; 
  output out=percentiles pctlpre=P_ pctlpts= 50, 75 to 100 by 5;
run;

proc sql noprint;
  select 
    name, 
    cats(':',name)
  into 
    :COL_NAMES separated by ',', 
    :MVAR_NAMES separated by ','
  from sashelp.vcolumn 
  where 
    libname = "WORK" 
    and memname = "PERCENTILES"
  ;
  select &COL_NAMES into &MVAR_NAMES
  from percentiles;
quit;

结果:每个百分位数 1 个宏变量,与单变量输出同名。