有没有办法返回SAS上的特定行号?

有没有办法返回SAS上的特定行号?,sas,dataset,Sas,Dataset,以下是数据集的一部分: Obs Buffer ... 75 14 76 13 77 64 78 38.1% 79 29.2% 80 69.2% 81 33 82 5-12 ... 我只需要包含“%”和前面两行的数据。例如,在本例中,我要拉出“13”、“64”、“38.1%”、“29.2%”和“69.2%” 有什么方法可以做到这一点吗?回答您的问题:变量\N\u将返回数据步骤循环通过数据语句的

以下是数据集的一部分:

   Obs Buffer
     ...
    75 14
    76 13 
    77 64 
    78 38.1% 
    79 29.2% 
    80 69.2% 
    81 33 
    82 5-12
     ... 
我只需要包含“%”和前面两行的数据。例如,在本例中,我要拉出“13”、“64”、“38.1%”、“29.2%”和“69.2%”


有什么方法可以做到这一点吗?

回答您的问题:变量
\N\u
将返回数据步骤循环通过数据语句的次数。()

但是,要解决您的问题,请使用
lag()
()和contains语句,例如

data justBuffers;
    set yourDS;
    twoBefore = lag2(Buffer);
    oneBefore = lag1(Buffer);
    if Buffer ? '%' then do;
        if not missing(twoBefore) then do;
            x = twoBefore;
            output;
        end;
        if not missing(oneBefore) then do;
            x = oneBefore;
            output;
        end;
        x = Buffer;
        output;
        call missing(oneBefore, twoBefore);
    end;
    keep x;
run;

我还没有测试代码,所以要小心!我相信您可以使它更平滑。

回答您的问题:
\N\u
变量将返回数据步骤循环通过数据语句的次数。()

但是,要解决您的问题,请使用
lag()
()和contains语句,例如

data justBuffers;
    set yourDS;
    twoBefore = lag2(Buffer);
    oneBefore = lag1(Buffer);
    if Buffer ? '%' then do;
        if not missing(twoBefore) then do;
            x = twoBefore;
            output;
        end;
        if not missing(oneBefore) then do;
            x = oneBefore;
            output;
        end;
        x = Buffer;
        output;
        call missing(oneBefore, twoBefore);
    end;
    keep x;
run;

我还没有测试代码,所以要小心!我相信你可以让它更平滑。

我喜欢用
点来做这类事情<代码>\u N
作为行计数器是可靠的,只要您对数据步循环不做任何有趣的事情

data have;
length buffer $50;
input obs buffer $;
datalines;
75 14
76 13 
77 64 
78 38.1% 
79 29.2% 
80 69.2% 
81 33 
82 5-12
;;;;
run;
data want;
set have;
pointer=_N_;
if find(buffer,'%') then do;
  output;
  pointer=_N_-1;
  set have point=pointer;
  if not (find(buffer,'%')) then do;
    output;
    pointer=_N_-2;
    set have point=pointer;
    if not (find(buffer,'%')) then output;
  end; 
end;
run;
如果您需要恢复订单,您可以在之后按
指针
进行排序(或者
obs
,如果这是一个实变量-我假设不是)。如果
obs
确实是一个实变量(或者如果您使用视图将其变为实变量),那么在SQL中有一种有趣的方法可以做到这一点:

proc sql;
create table want as
    select H.* from have H 
        left join have V on H.obs=V.obs-1
        left join have A on H.obs=A.obs-2
        where 
            (find(H.buffer,'%'))
            or
            (find(V.buffer,'%'))
            or
            (find(A.buffer,'%'))
        order by H.obs
        ;
quit;
如何在没有数据通道的情况下实现obs:

data have_vw/view=have_vw;
set have;
obs=_n_;
run;

然后在SQL查询中使用
have\u vw
而不是
have
(在所有三个点中)。

我喜欢使用
point
来处理这类事情<代码>\u N作为行计数器是可靠的,只要您对数据步循环不做任何有趣的事情

data have;
length buffer $50;
input obs buffer $;
datalines;
75 14
76 13 
77 64 
78 38.1% 
79 29.2% 
80 69.2% 
81 33 
82 5-12
;;;;
run;
data want;
set have;
pointer=_N_;
if find(buffer,'%') then do;
  output;
  pointer=_N_-1;
  set have point=pointer;
  if not (find(buffer,'%')) then do;
    output;
    pointer=_N_-2;
    set have point=pointer;
    if not (find(buffer,'%')) then output;
  end; 
end;
run;
如果您需要恢复订单,您可以在之后按
指针
进行排序(或者
obs
,如果这是一个实变量-我假设不是)。如果
obs
确实是一个实变量(或者如果您使用视图将其变为实变量),那么在SQL中有一种有趣的方法可以做到这一点:

proc sql;
create table want as
    select H.* from have H 
        left join have V on H.obs=V.obs-1
        left join have A on H.obs=A.obs-2
        where 
            (find(H.buffer,'%'))
            or
            (find(V.buffer,'%'))
            or
            (find(A.buffer,'%'))
        order by H.obs
        ;
quit;
如何在没有数据通道的情况下实现obs:

data have_vw/view=have_vw;
set have;
obs=_n_;
run;

然后在SQL查询中(在所有三个点中)使用
have
而不是

通过遵循功夫的思想,我得到下面的代码,它可以工作

data adjust;
set source;
oneBefore = lag1(Buffer);
twoBefore = lag2(Buffer);
threeBefore = lag3(Buffer);
fourBefore = lag4(Buffer);
if index(buffer,'%')^=0 and index(onebefore,'%')^=0 and index(twobefore,'%')^=0then do;
        x = fourBefore;
        output;
        x = threeBefore;
        output;
        x = twoBefore;
        output;
        x = oneBefore;
        output;
        x=buffer;
       output;
    end;
  keep x;
run;

通过遵循功夫果酱的思想,我得到了下面的代码,它可以正常工作

data adjust;
set source;
oneBefore = lag1(Buffer);
twoBefore = lag2(Buffer);
threeBefore = lag3(Buffer);
fourBefore = lag4(Buffer);
if index(buffer,'%')^=0 and index(onebefore,'%')^=0 and index(twobefore,'%')^=0then do;
        x = fourBefore;
        output;
        x = threeBefore;
        output;
        x = twoBefore;
        output;
        x = oneBefore;
        output;
        x=buffer;
       output;
    end;
  keep x;
run;

作为旁注,您可以通过预读合并(
merge-have(in=a)have(in=b-firstobs=2)have(in=c-firstobs=3)
)在常规SAS中复制SQL join解决方案,如果这会使您的船漂浮。SQL解决方案较短,因此我的首选,但没有那么大的不同。顺便说一句,您可以通过预读合并(
merge have(in=a)have(in=b firstobs=2)have(in=c firstobs=3)
)在常规SAS中复制SQL join解决方案,如果这会使您的船漂浮。SQL解决方案较短,因此我更喜欢,但没有那么大的不同。