计算数据步骤中连续出现的次数

count consecutive occurrence in data step

Pos Series Res
--- ------ ---
A   1      1
A   1      1
A   1      0
A   1      -1
.
.
B   3      1
B   3     -1

Res 的唯一可能值为 1,0,-1。我的目标是计算每个系列的 1-1 连续 K 出现的次数,其中 K 由用户定义。

示例: 1 1 -1 1 1 1 0 0 1

K = 2,输出为3

K = 3,输出为1.

K > 3,输出为0.

问题

如果 k 是固定的,那么我可以使用 lag 来完成。但是我不知道如何用动态 k 来处理这个问题。

data Want;
   set Have;
   prev1 = lag1(Res);
   prev2 = lag2(Res);
   prev3 = lag3(Res);
   if first.Pos  or Series = 1 then call missing(prev1,prev2,prev3);
   if Series = 2 then call missing(prev2,prev3);
   if Series = 3 then call missing(prev3);
   N = sum(of prev:);
run;

proc sql noprint;
   select count(*), N
   from WANT
   group by N;
quit;

执行此操作的最简单方法是不存在延迟。

data have;
input Pos $ Series Res;
datalines;
A   1      1
A   1      1
A   1      0
A   1      -1
A   1      1
A   1      1
A   1      1
A   1      0
B   3      1
B   3     -1
B   3      1
B   3      1
;;;;
run;

%let k=2;
data want;
  set have;
  array inRow[-1:1] seriesM1 seriesZero seriesP1;
  by pos series res notsorted;
  if first.res then consec=0;
  if first.series then do;
    inRow[-1]=0;
    inRow[1]=0;
  end;
  consec+1;
  if consec >= &k and res ne 0 then inRow[res]+1;
  if last.series then output;
run;

我在这里对你如何处理 'k in a row' 较长的行做了一些假设,但它应该给出合理假设的正确答案(对于任何 M > K,你有 (M-K)+1 K - 连续)。

基本上,您可以使用带有 NOTSORTED 的 BY 语句来计算变量中的运行次数,因为如果它不是 NOTSORTED,它将首先重置。每次它达到一个新值时,无论这些值的顺序如何。因此,您可以利用这一点,而 tada,您知道到目前为止您连续看到了多少。然后将其与 k 进行比较,您就设置好了。