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 个宏变量,与单变量输出同名。
我有以下代码来计算百分位数。
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 个宏变量,与单变量输出同名。