获取SAS中多变量的中位数和第95百分位统计信息
我目前正在尝试从数据集中提取一个中位数和第95个百分位数,这是我在SAS 9.4中的部分工作,但是我找不到一个简单的或有效的方法。我有以下形式的数据:获取SAS中多变量的中位数和第95百分位统计信息,sas,mean,median,Sas,Mean,Median,我目前正在尝试从数据集中提取一个中位数和第95个百分位数,这是我在SAS 9.4中的部分工作,但是我找不到一个简单的或有效的方法。我有以下形式的数据: NAME TREATMENT DATE week0 week1 week2 week3 week4 week5 week6 week7 CCG1 Treatment1 APR16 1 1 3 2 4 0 0 0 CCG1 Treatment2 APR16 0 0 2 12 0 3 5 0 我想做的是找到治疗所需的周数中位数以及治
NAME TREATMENT DATE week0 week1 week2 week3 week4 week5 week6 week7
CCG1 Treatment1 APR16 1 1 3 2 4 0 0 0
CCG1 Treatment2 APR16 0 0 2 12 0 3 5 0
我想做的是找到治疗所需的周数中位数以及治疗时间的第95个百分位数
我已经研究了过程均值和单变量,但是无论我尝试什么,都倾向于在垂直计算中进行统计,而不是在水平计算中。我也看了转置,但它并没有完全做到这一点,因为它在这个过程中丢失了数据。数据集的示例如下所示。如果有人能给我指出正确的方向,我将不胜感激 如果每行有固定数量的列(周);您可以使用
Mean()
和median()
函数
输入数据:
data have;
length TREATMENT $10;
input NAME $ TREATMENT $ DATE $ week0 week1 week2 week3 week4 week5 week6 week7;
datalines;
CCG1 Treatment1 APR16 1 1 3 2 4 0 0 0
CCG1 Treatment2 APR16 0 0 2 12 0 3 5 0
;
run;
代码:
输出:
TREATMENT=Treatment1 NAME=CCG1 DATE=APR16 MEDIAN=1 MEAN=1.375
TREATMENT=Treatment2 NAME=CCG1 DATE=APR16 MEDIAN=1 MEAN=2.75
如果每行有固定数量的列(周);您可以使用
Mean()
和median()
函数
输入数据:
data have;
length TREATMENT $10;
input NAME $ TREATMENT $ DATE $ week0 week1 week2 week3 week4 week5 week6 week7;
datalines;
CCG1 Treatment1 APR16 1 1 3 2 4 0 0 0
CCG1 Treatment2 APR16 0 0 2 12 0 3 5 0
;
run;
代码:
输出:
TREATMENT=Treatment1 NAME=CCG1 DATE=APR16 MEDIAN=1 MEAN=1.375
TREATMENT=Treatment2 NAME=CCG1 DATE=APR16 MEDIAN=1 MEAN=2.75
使用分组转换数据。这将使它更容易使用
proc transpose data=have
out=want(rename=(COL1 = Value) )
name=week
;
by Name Treatment Date;
var week0-week7;
run;
proc means data=want median p95;
by Name Treatment Date;
var value;
run;
使用分组转换数据。这将使它更容易使用
proc transpose data=have
out=want(rename=(COL1 = Value) )
name=week
;
by Name Treatment Date;
var week0-week7;
run;
proc means data=want median p95;
by Name Treatment Date;
var value;
run;
计算
中值后
对周值进行迭代,以找到第一个最接近的值
data want;
set have;
array x week:;
median = median(of x(*));
diff = 1e12;
do i = 1 to dim(x);
p = x(i);
if abs(p-median) < diff then do;
first_var_nearest_median = vname(x(i));
diff = abs(p-median);
end;
end;
run;
保罗的快速排序宏
%Macro Qsort (
Arr = /* Parallel array name list */
, By = %QScan(&Arr,1,%Str( )) /* Key array name */
, Seq = A /* Seq=D for descending */
, LB = Lbound(&By) /* Lower bound to sort */
, HB = Hbound(&By) /* Upper bound to sort */
, M = 9 /* Tuning range: [1:15] */
);
/*==================================================================+
| Name: Qsort. |
|===================================================================|
| Developer: Paul M. Dorfman. |
|===================================================================|
| Function: Sort array in place via the QuickSort algorithm. |
|===================================================================|
| General: |
|-------------------------------------------------------------------|
| Qsort is a macro call routine designed to be invoked from within |
| a DATA step to sort a single-subscripted array or a parallel list |
| of N arrays using one array as a key. The array(s) can be arrays |
| SAS variables or a temporary array; numeric or character. Arrays |
| in the list do not have to be the same type and/or item length. |
| |
| The kernel of the routine is a DATA step implementation of the |
| QuickSort algorithm (C.A.R. Hoare, 1960). Final ordering is done |
| by a single sweep of the modified insertion sort after quicksort |
| has reduced all array subpartitions to no more than &M items. |
|-------------------------------------------------------------------|
| Performance: |
|-------------------------------------------------------------------|
| Run-time increases as N*log2(N), where N is the number of array |
| elements to be sorted. As a benchmark, a random numeric temporary |
| array is sorted into ascending order in lt 1 CPU sec under OS/390 |
| IBM model 9672 R36 running SAS version 8.0. |
|===================================================================|
| Usage examples: |
|===================================================================|
| 1. Sorting entire array A ascending (semicolon is optional): |
| |
| %Qsort (Arr=A, Seq=a); |
| |
| or simply, using Seq=a default, |
| |
| %Qsort (Arr=A); |
|-------------------------------------------------------------------|
| 2. Sorting entire array B descending: |
| |
| %Qsort (Arr=B, Seq=d); |
|-------------------------------------------------------------------|
| 3. Sorting elements -12345 through 12345 of array Z ascending, |
| leaving the rest of the items intact; |
| |
| %Qsort (Arr=Z, first=-12345, last=12345); |
|-------------------------------------------------------------------|
| 4. Sorting first 100 elements of array C descending, the rest - |
| ascending: |
| |
| %Qsort (Arr=C, Seq=d, last= 100); |
| %Qsort (Arr=C, Seq=a, first=101); |
|-------------------------------------------------------------------|
| 5. Sorting first half of array D ascending, second half - |
| descending: |
| |
| half = int((lbound(D)+hbound(D))*.5); |
| %Qsort (Arr=D, Seq=D, last=half ); |
| %Qsort (Arr=D, Seq=A, first=half+1); |
| |
| or without HALF and omitting Seq=A by default: |
| |
| %Qsort (Arr=D, Seq=D, last= (lbound(D)+hbound(D))*.5 ); |
| %Qsort (Arr=D, first=(lbound(D)+hbound(D))*.5+1); |
|-------------------------------------------------------------------|
| 6. Doing the same as in 5 without the auxiliary variable HALF |
| and omitting Seq=A by default: |
| |
| %Qsort (Arr=D, Seq=D, last= (lbound(D)+hbound(D))*.5 ); |
| %Qsort (Arr=D, first=(lbound(D)+hbound(D))*.5+1); |
|-------------------------------------------------------------------|
| 7. Sorting parallel arrays A B C using array B as the key array: |
| |
| %Qsort (Arr=A B C, By=C) ; |
| |
| Illustration. The following step uses array C as a key: |
| ------------ |
| data _null_; |
| array a(10) ( 9 8 7 6 5 4 3 2 1 0 ); |
| array b(10) $ ('a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j'); |
| array c(10) ( 0 1 2 3 4 5 6 7 8 9 ); |
| %Qsort (Arr=A B C, By=C, Seq=D); |
| put A(*) / B(*) / C(*); |
| run; |
| |
| It prints the following in the log: |
| |
| 0 1 2 3 4 5 6 7 8 9 |
| j i h g f e d c b a |
| 9 8 7 6 5 4 3 2 1 0 |
| |
| Note: QuickSort is an unstable algorithm, i.e. if the key array|
| ---------------------------------------- |
| has ties (duplicate keys), subordinate array elements DO NOT |
| --------------------------------- |
| retain their original relative order. This behavior is similar |
| ------------------------------------ |
| to that of Proc Sort with NOEQUALS option. |
| The parallel array feature is most useful when it is necessary |
| to perform and indirect sort, i.e. with a single parallel array|
| containing pointers to long 'records'. For instance, instead of|
| giving Qsort the labor of ordering 20 parallel arrays, it is |
| more efficient to store the pointers of the arrays in a single |
| parallel array, and then finish the entire thing using a sweep |
| of indirect sorting. |
| |
| Note: When using LB= and HB= options with parallel arrays, ALL |
| ---------------------------------------- |
| lower array bounds must be GE LB=value. Likewise, the upper |
| bounds must all be LE than HB= value. As long as the domain of |
| ALL indices lies within an LB= and HB, the indexing of arrays |
| on the list can be arbitrary (in particular, negative). |
|===================================================================|
| Arguments: |
|-------------------------------------------------------------------|
| Parameter Usage Description |
|-------------------------------------------------------------------|
| Arr= Required The name of the array (or list of any number |
| of parallel arrays) to be sorted. By default,|
| the first array in the list becomes the key |
| array, and the rest of the arrays are permut-|
| ed accordingly. |
|-------------------------------------------------------------------|
| By= Optional The name of the key array in the list. If the|
| list consists of a single array, it is the |
| key array itself - along with the rule above.|
| See usage for more details. |
|-------------------------------------------------------------------|
| Seq= Optional Sorting sequence. Ascending is default. To |
| specify it explicitly, set Seq=A (any case). |
| Anything else will result in the array sorted|
| decsending. |
|-------------------------------------------------------------------|
| LB= Optional The indices of the first and last array |
| HB= Numeric elements to be included into sorting. You |
| can specify any valid numeric SAS expression,|
| hardcoded numeric value, or a macrovariable |
| reference resolving to any of the above. The |
| values of these parms default to the lower |
| and upper bounds. |
| Use LB= and HB= parameters if you need only |
| part of the array to be ordered, or if you |
| want different parts ordered differently, |
| which can be achieved by issuing two or more|
| consecutive calls to Qsort with LB= and HB= |
| specified accordingly (see Usage above). |
|-------------------------------------------------------------------|
| M= Optional Tuning parm: The largest subpartition size |
| Numeric Quicksort attempts to partition further. Any |
| subpartition LE &M is passed to the straight |
| insertion sort. &M=1 corresponds to 'pure' |
| Quicksort working until all subpartitions |
| have been reduced to just 1 element. &M=9 is |
| optimal. Variations from 5 to 15 affect the |
| sorting speed very slightly. Best advice as |
| to M= : Leave it alone at 9. |
+===================================================================*/
%Local _ H I J L N P Q S T W;
%Macro Swap (I,J);
%Local W;
Do;
%Do W = 1 %To &N;
&T&W = &&A&W(&I);
&&A&W(&I) = &&A&W(&J);
&&A&W(&J) = &T&W ;
%End;
End;
%Mend Swap;
%If %Upcase(&Seq) = %Upcase(A) %Then %Let Q = G;
%Else %Let Q = L;
%Do %Until (&&A&N EQ );
%Let N = %Eval(&N + 1);
%Local A&N;
%Let A&N = %Scan(&Arr,&N,%Str( ));
%End;
%Let N = %Eval(&N - 1);
%Let _ = %Substr(%Sysfunc(Ranuni(0)),3,
%Eval(7 - %Length(&N) + 5*(%Substr(&Sysver,1,1) GT 6)));
%Let H = H&_; %Let I = I&_; %Let J = J&_; %Let L = L&_;
%Let P = P&_; %Let S = S&_; %Let T = T&_; %Let Z = Z&_;
Array &Z (0:1, 0:50) _Temporary_;
&L = &LB; &H = &HB;
If &H - &L GT &M Then Do &S=1 By 0 While (&S);
&J = (&H - &L)/3; &I = &L + &J; &J = &I + &J;
If &By(&L) &Q.T &By(&I) Then %Swap(&L,&I);
If &By(&I) &Q.T &By(&J) Then %Swap(&I,&J);
If &By(&J) &Q.T &By(&H) Then %Swap(&J,&H);
If &By(&L) &Q.T &By(&I) Then %Swap(&L,&I);
If &By(&I) &Q.T &By(&J) Then %Swap(&I,&J);
If &By(&L) &Q.T &By(&I) Then %Swap(&L,&I);
%If &M LE 3 %Then %Do;
If &H - &L LE 3 Then Do;
&L = &Z(0,&S); &H = &Z(1,&S); &S +- 1;
Continue;
End;
%End;
%Swap(&L,&I); &P = &By(&L); &I = &L;
Do &J=&H + 1 By 0;
Do &I=&I + 1 By + 1 Until(&By(&I) &Q.E &P); End;
Do &J=&J - 1 By - 1 Until(&P &Q.E &By(&J)); End;
If &I GE &J Then Leave;
%Swap(&I,&J);
End;
%Swap(&L,&J);
If &H - &J GE &J - &L GT &M Then Do &S = &S + 1;
&Z(0,&S) = &J + 1; &Z(1,&S) = &H; &H = &J - 1;
End;
Else If &J - &L GE &H - &J GT &M Then Do &S = &S + 1;
&Z(0,&S) = &L; &Z(1,&S) = &J - 1; &L = &J + 1;
End;
Else If &J - &L GT &M GE &H - &J Then &H = &J - 1;
Else If &H - &J GT &M GE &J - &L Then &L = &J + 1;
Else Do;
&L = &Z(0,&S); &H = &Z(1,&S); &S +- 1;
End;
End;
%If &M = 1 %Then %Goto Exit;
Do &J = &LB + 1 To &HB;
If &By(&J - 1) &Q.T &By(&J) Then Do;
&P = &By(&J);
%Do W = 1 %To &N;
%If &&A&W Ne &By %Then &T&W = &&A&W(&J) ; ;
%End;
Do &I = &J - 1 To &LB By - 1;
If &P &Q.E &By(&I) Then Leave;
%Do W = 1 %To &N;
&&A&W(&I + 1) = &&A&W(&I);
%End;
End;
&By(&I + 1) = &P;
%Do W = 1 %To &N;
%If &&A&W Ne &By %Then &&A&W(&I + 1) = &T&W ; ;
%End;
End;
End;
%Exit: Drop &H &I &J &L &P &S T&_:;
%Mend Qsort;
计算
中值后
对周值进行迭代,以找到第一个最接近的值
data want;
set have;
array x week:;
median = median(of x(*));
diff = 1e12;
do i = 1 to dim(x);
p = x(i);
if abs(p-median) < diff then do;
first_var_nearest_median = vname(x(i));
diff = abs(p-median);
end;
end;
run;
保罗的快速排序宏
%Macro Qsort (
Arr = /* Parallel array name list */
, By = %QScan(&Arr,1,%Str( )) /* Key array name */
, Seq = A /* Seq=D for descending */
, LB = Lbound(&By) /* Lower bound to sort */
, HB = Hbound(&By) /* Upper bound to sort */
, M = 9 /* Tuning range: [1:15] */
);
/*==================================================================+
| Name: Qsort. |
|===================================================================|
| Developer: Paul M. Dorfman. |
|===================================================================|
| Function: Sort array in place via the QuickSort algorithm. |
|===================================================================|
| General: |
|-------------------------------------------------------------------|
| Qsort is a macro call routine designed to be invoked from within |
| a DATA step to sort a single-subscripted array or a parallel list |
| of N arrays using one array as a key. The array(s) can be arrays |
| SAS variables or a temporary array; numeric or character. Arrays |
| in the list do not have to be the same type and/or item length. |
| |
| The kernel of the routine is a DATA step implementation of the |
| QuickSort algorithm (C.A.R. Hoare, 1960). Final ordering is done |
| by a single sweep of the modified insertion sort after quicksort |
| has reduced all array subpartitions to no more than &M items. |
|-------------------------------------------------------------------|
| Performance: |
|-------------------------------------------------------------------|
| Run-time increases as N*log2(N), where N is the number of array |
| elements to be sorted. As a benchmark, a random numeric temporary |
| array is sorted into ascending order in lt 1 CPU sec under OS/390 |
| IBM model 9672 R36 running SAS version 8.0. |
|===================================================================|
| Usage examples: |
|===================================================================|
| 1. Sorting entire array A ascending (semicolon is optional): |
| |
| %Qsort (Arr=A, Seq=a); |
| |
| or simply, using Seq=a default, |
| |
| %Qsort (Arr=A); |
|-------------------------------------------------------------------|
| 2. Sorting entire array B descending: |
| |
| %Qsort (Arr=B, Seq=d); |
|-------------------------------------------------------------------|
| 3. Sorting elements -12345 through 12345 of array Z ascending, |
| leaving the rest of the items intact; |
| |
| %Qsort (Arr=Z, first=-12345, last=12345); |
|-------------------------------------------------------------------|
| 4. Sorting first 100 elements of array C descending, the rest - |
| ascending: |
| |
| %Qsort (Arr=C, Seq=d, last= 100); |
| %Qsort (Arr=C, Seq=a, first=101); |
|-------------------------------------------------------------------|
| 5. Sorting first half of array D ascending, second half - |
| descending: |
| |
| half = int((lbound(D)+hbound(D))*.5); |
| %Qsort (Arr=D, Seq=D, last=half ); |
| %Qsort (Arr=D, Seq=A, first=half+1); |
| |
| or without HALF and omitting Seq=A by default: |
| |
| %Qsort (Arr=D, Seq=D, last= (lbound(D)+hbound(D))*.5 ); |
| %Qsort (Arr=D, first=(lbound(D)+hbound(D))*.5+1); |
|-------------------------------------------------------------------|
| 6. Doing the same as in 5 without the auxiliary variable HALF |
| and omitting Seq=A by default: |
| |
| %Qsort (Arr=D, Seq=D, last= (lbound(D)+hbound(D))*.5 ); |
| %Qsort (Arr=D, first=(lbound(D)+hbound(D))*.5+1); |
|-------------------------------------------------------------------|
| 7. Sorting parallel arrays A B C using array B as the key array: |
| |
| %Qsort (Arr=A B C, By=C) ; |
| |
| Illustration. The following step uses array C as a key: |
| ------------ |
| data _null_; |
| array a(10) ( 9 8 7 6 5 4 3 2 1 0 ); |
| array b(10) $ ('a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j'); |
| array c(10) ( 0 1 2 3 4 5 6 7 8 9 ); |
| %Qsort (Arr=A B C, By=C, Seq=D); |
| put A(*) / B(*) / C(*); |
| run; |
| |
| It prints the following in the log: |
| |
| 0 1 2 3 4 5 6 7 8 9 |
| j i h g f e d c b a |
| 9 8 7 6 5 4 3 2 1 0 |
| |
| Note: QuickSort is an unstable algorithm, i.e. if the key array|
| ---------------------------------------- |
| has ties (duplicate keys), subordinate array elements DO NOT |
| --------------------------------- |
| retain their original relative order. This behavior is similar |
| ------------------------------------ |
| to that of Proc Sort with NOEQUALS option. |
| The parallel array feature is most useful when it is necessary |
| to perform and indirect sort, i.e. with a single parallel array|
| containing pointers to long 'records'. For instance, instead of|
| giving Qsort the labor of ordering 20 parallel arrays, it is |
| more efficient to store the pointers of the arrays in a single |
| parallel array, and then finish the entire thing using a sweep |
| of indirect sorting. |
| |
| Note: When using LB= and HB= options with parallel arrays, ALL |
| ---------------------------------------- |
| lower array bounds must be GE LB=value. Likewise, the upper |
| bounds must all be LE than HB= value. As long as the domain of |
| ALL indices lies within an LB= and HB, the indexing of arrays |
| on the list can be arbitrary (in particular, negative). |
|===================================================================|
| Arguments: |
|-------------------------------------------------------------------|
| Parameter Usage Description |
|-------------------------------------------------------------------|
| Arr= Required The name of the array (or list of any number |
| of parallel arrays) to be sorted. By default,|
| the first array in the list becomes the key |
| array, and the rest of the arrays are permut-|
| ed accordingly. |
|-------------------------------------------------------------------|
| By= Optional The name of the key array in the list. If the|
| list consists of a single array, it is the |
| key array itself - along with the rule above.|
| See usage for more details. |
|-------------------------------------------------------------------|
| Seq= Optional Sorting sequence. Ascending is default. To |
| specify it explicitly, set Seq=A (any case). |
| Anything else will result in the array sorted|
| decsending. |
|-------------------------------------------------------------------|
| LB= Optional The indices of the first and last array |
| HB= Numeric elements to be included into sorting. You |
| can specify any valid numeric SAS expression,|
| hardcoded numeric value, or a macrovariable |
| reference resolving to any of the above. The |
| values of these parms default to the lower |
| and upper bounds. |
| Use LB= and HB= parameters if you need only |
| part of the array to be ordered, or if you |
| want different parts ordered differently, |
| which can be achieved by issuing two or more|
| consecutive calls to Qsort with LB= and HB= |
| specified accordingly (see Usage above). |
|-------------------------------------------------------------------|
| M= Optional Tuning parm: The largest subpartition size |
| Numeric Quicksort attempts to partition further. Any |
| subpartition LE &M is passed to the straight |
| insertion sort. &M=1 corresponds to 'pure' |
| Quicksort working until all subpartitions |
| have been reduced to just 1 element. &M=9 is |
| optimal. Variations from 5 to 15 affect the |
| sorting speed very slightly. Best advice as |
| to M= : Leave it alone at 9. |
+===================================================================*/
%Local _ H I J L N P Q S T W;
%Macro Swap (I,J);
%Local W;
Do;
%Do W = 1 %To &N;
&T&W = &&A&W(&I);
&&A&W(&I) = &&A&W(&J);
&&A&W(&J) = &T&W ;
%End;
End;
%Mend Swap;
%If %Upcase(&Seq) = %Upcase(A) %Then %Let Q = G;
%Else %Let Q = L;
%Do %Until (&&A&N EQ );
%Let N = %Eval(&N + 1);
%Local A&N;
%Let A&N = %Scan(&Arr,&N,%Str( ));
%End;
%Let N = %Eval(&N - 1);
%Let _ = %Substr(%Sysfunc(Ranuni(0)),3,
%Eval(7 - %Length(&N) + 5*(%Substr(&Sysver,1,1) GT 6)));
%Let H = H&_; %Let I = I&_; %Let J = J&_; %Let L = L&_;
%Let P = P&_; %Let S = S&_; %Let T = T&_; %Let Z = Z&_;
Array &Z (0:1, 0:50) _Temporary_;
&L = &LB; &H = &HB;
If &H - &L GT &M Then Do &S=1 By 0 While (&S);
&J = (&H - &L)/3; &I = &L + &J; &J = &I + &J;
If &By(&L) &Q.T &By(&I) Then %Swap(&L,&I);
If &By(&I) &Q.T &By(&J) Then %Swap(&I,&J);
If &By(&J) &Q.T &By(&H) Then %Swap(&J,&H);
If &By(&L) &Q.T &By(&I) Then %Swap(&L,&I);
If &By(&I) &Q.T &By(&J) Then %Swap(&I,&J);
If &By(&L) &Q.T &By(&I) Then %Swap(&L,&I);
%If &M LE 3 %Then %Do;
If &H - &L LE 3 Then Do;
&L = &Z(0,&S); &H = &Z(1,&S); &S +- 1;
Continue;
End;
%End;
%Swap(&L,&I); &P = &By(&L); &I = &L;
Do &J=&H + 1 By 0;
Do &I=&I + 1 By + 1 Until(&By(&I) &Q.E &P); End;
Do &J=&J - 1 By - 1 Until(&P &Q.E &By(&J)); End;
If &I GE &J Then Leave;
%Swap(&I,&J);
End;
%Swap(&L,&J);
If &H - &J GE &J - &L GT &M Then Do &S = &S + 1;
&Z(0,&S) = &J + 1; &Z(1,&S) = &H; &H = &J - 1;
End;
Else If &J - &L GE &H - &J GT &M Then Do &S = &S + 1;
&Z(0,&S) = &L; &Z(1,&S) = &J - 1; &L = &J + 1;
End;
Else If &J - &L GT &M GE &H - &J Then &H = &J - 1;
Else If &H - &J GT &M GE &J - &L Then &L = &J + 1;
Else Do;
&L = &Z(0,&S); &H = &Z(1,&S); &S +- 1;
End;
End;
%If &M = 1 %Then %Goto Exit;
Do &J = &LB + 1 To &HB;
If &By(&J - 1) &Q.T &By(&J) Then Do;
&P = &By(&J);
%Do W = 1 %To &N;
%If &&A&W Ne &By %Then &T&W = &&A&W(&J) ; ;
%End;
Do &I = &J - 1 To &LB By - 1;
If &P &Q.E &By(&I) Then Leave;
%Do W = 1 %To &N;
&&A&W(&I + 1) = &&A&W(&I);
%End;
End;
&By(&I + 1) = &P;
%Do W = 1 %To &N;
%If &&A&W Ne &By %Then &&A&W(&I + 1) = &T&W ; ;
%End;
End;
End;
%Exit: Drop &H &I &J &L &P &S T&_:;
%Mend Qsort;
试试proc的意思。每行有多少个星期字段?是七个固定的星期吗?请添加一个示例,说明您希望输出的外观。我将在答案中为您输入代码。总共有53周的行。我正在使用在这里找到的已承认专员文件的专员选项卡Try proc means。每行有多少个星期字段?是七个固定的星期吗?请添加一个示例,说明您希望输出的外观。我将在答案中为您输入代码。总共有53周的行。我正在使用此处发现的已承认的专员文件的专员选项卡。这假设每个治疗都有一行,这是OP显示的,但获得这些数据的方式非常奇怪。很可能是一个人,每次治疗,每排,然后这就行不通了。如果每个治疗一行的假设是正确的,那么答案没有错。这似乎是可行的,但仔细检查,它会给出该行数值的中位数。我可能没有明确说明的是,我希望每周的中位数能够得到治疗。我试着将week变量放入一个数组中,并将这些值与数组中该周的索引号相乘。这也没有给我所需要的。这假设每个治疗都有一条线,这是OP所显示的,但获得这些数据的方式非常奇怪。很可能是一个人,每次治疗,每排,然后这就行不通了。如果每个治疗一行的假设是正确的,那么答案没有错。这似乎是可行的,但仔细检查,它会给出该行数值的中位数。我可能没有明确说明的是,我希望每周的中位数能够得到治疗。我试着将week变量放入一个数组中,并将这些值与数组中该周的索引号相乘。这也没有给我所需要的。