我有一个数据集(已经按血压变量排序)
Blood Pressure
87
99
99
109
111
112
117
119
121
123
139
143
145
151
165
198
我需要在不使用proc手段的情况下找到中位数。现在,对于这些数据,有16个观测值。中位数为(119+121)/2=120。
如何进行编码,以便始终能够找到中值,无论有多少观测值。适用于偶数个观测值和奇数个观测值的代码。
当然,PROC的意思是不允许。
谢谢。
我为此使用了一个FCMP函数。这是我个人库中的一个通用分位数函数。由于中位数是50%的瓦片,这将起作用。
options cmplib=work.fns;
data input;
input BP;
datalines;
87
99
99
109
111
112
117
119
121
123
139
143
145
151
165
198
;run;
proc fcmp outlib=work.fns.fns;
function qtile_n(p, arr[*], n);
alphap=1;
betap=1;
if n > 1 then do;
m = alphap+p*(1-alphap-betap);
i = floor(n*p+m);
g = n*p + m - i;
qp = (1-g)*arr[i] + g*arr[i+1];
end;
else
qp = arr[1];
return(qp);
endsub;
quit;
proc sql noprint;
select count(*) into :n from input;
quit;
data _null_;
set input end=last;
array v[&n] _temporary_;
v[_n_] = bp;
if last then do;
med = qtile_n(.5,v,&n);
put med=;
end;
run;
假设您有一个名为have的数据集,按变量BP排序,您可以尝试以下操作:
data want(keep=median);
if mod(nobs,2) = 0 then do; /* even number if records in data set */
j = nobs / 2;
set HAVE(keep=bp) point=j nobs=nobs;
k = bp; /* hold value in temp variable */
j + 1;
set HAVE(keep=bp) point=j nobs=nobs;
median = (k + bp) / 2;
end;
else do;
j = round( nobs / 2 );
set HAVE(keep=bp) point=j nobs=nobs;
median = bp;
end;
put median=; /* if all you want is to see the result */
output; /* if you want it in a new data set */
stop; /* stop required to prevent infinite loop */
run;
这是"老式"的代码;我相信有人可以展示另一种使用哈希对象的解决方案,这可能会消除首先对数据进行排序的要求。