【问题标题】:SAS: Extract previous and next observationsSAS:提取上一个和下一个观察结果
【发布时间】:2018-10-13 02:41:11
【问题描述】:

我有一个这样的数据集(类型是一个指标):

 datetime         type
 ...
 ddmmyy:10:30:00  0
 ddmmyy:10:31:00  0
 ddmmyy:10:32:00  1
 ddmmyy:10:33:00  0
 ddmmyy:10:34:00  1
 ddmmyy:10:35:00  0
 ...

我试图提取类型 1 的数据以及上一个和下一个数据。只需尝试根据类型 1 提取 (-1,+1) 窗口。

datetime         type
...
ddmmyy:10:31:00  0
ddmmyy:10:32:00  1
ddmmyy:10:33:00  0
ddmmyy:10:34:00  1
ddmmyy:10:35:00  0
...

我发现了一个类似的帖子here。我复制并粘贴了代码,但我不太确定他的代码中的“x”是什么意思。 SAS 给我“文件 WORK.x 不存在”。

有人可以帮帮我吗?谢谢。

【问题讨论】:

  • have(或链接中的x)在示例代码中用作输入数据集的占位符。例如,如果我要尝试为您提供此问题的代码,我将不得不使用该技巧,因为您没有在问题中说明输入数据集的名称。

标签: sas window extract next


【解决方案1】:

另一篇帖子中的X数据集就是你过滤的同一个源表,所以代码的逻辑顺序是:

  1. 检查“Have”表中的每一行,_N_ 保存当前行号,
  2. 如果 Type = 1 则 Set Have Point=_N_ 转到“Have”表中的行 _N_ 并将该行输出到新表“want”,然后继续到下一行。 _N_ 可以是指向当前行、上一行或下一行的指针。 (两个 IF 语句处理第一行和最后一行的情况;没有上一个或没有下一个)

完整的工作代码:

data have;
length datetime $23.;
input datetime $ type ;
datalines;
ddmmyy:10:30:00  0
ddmmyy:10:31:00  0
ddmmyy:10:32:00  1
ddmmyy:10:33:00  0
ddmmyy:10:34:00  1
ddmmyy:10:35:00  0
;
run;

data want;
set have nobs=nobs;
if type = 1 then do;
  current = _N_;
  prev = current - 1;
  next = current + 1;

  if prev > 0 then do;
    set have point = prev;
    output;
  end;

  set have point = current;
  output;

  if next <= nobs then do;
    set have point = next;
    output;
  end;
end;
run;

 proc sort data=want noduprecs;
      by _all_ ; Run;

注意:我添加了一个额外的步骤proc sort 来删除重复的行。

输出:

 datetime=ddmmyy:10:31:00 type=0
 datetime=ddmmyy:10:32:00 type=1
 datetime=ddmmyy:10:33:00 type=0
 datetime=ddmmyy:10:34:00 type=1
 datetime=ddmmyy:10:35:00 type=0

【讨论】:

    【解决方案2】:

    对于没有任何 id 或 group 变量的示例数据,它应该非常简单。无需考虑在文件中来回移动,只需创建包含 TYPE 的前一个 (LAG_TYPE) 和下一个 (LEAD_TYPE) 值的新变量。然后,您在 TYPE=1 之前保留观察的要求被转换为保留 LEAD_TYPE=1 的观察。

    让我们将您的样本数据转换为数据集。

    data have ;
      input datetime :$15. type ;
    cards;
    ddmmyy:10:30:00  0
    ddmmyy:10:31:00  0
    ddmmyy:10:32:00  1
    ddmmyy:10:33:00  0
    ddmmyy:10:34:00  1
    ddmmyy:10:35:00  0
    ;
    

    我将创建一个新变量 KEEP,而不是实际保留所需的观察结果,这对于满足您的标准的记录将是正确的。

    data want ;
      recno+1;
      set have end=eof;
      lag_type=lag(type);
      if not eof then set have(firstobs=2 keep=type rename=(type=lead_type));
      else lead_type=.;
      keep= (type=1 or lag_type=1 or lead_type=1) ;
    run;
    

    这是结果。

    recno       datetime        type    lag_type lead_type    keep
      1      ddmmyy:10:30:00      0         .         0        0
      2      ddmmyy:10:31:00      0         0         1        1
      3      ddmmyy:10:32:00      1         0         0        1
      4      ddmmyy:10:33:00      0         1         1        1
      5      ddmmyy:10:34:00      1         0         0        1
      6      ddmmyy:10:35:00      0         1         .        1
    

    【讨论】:

      【解决方案3】:

      上移下一个观测值并比较同一行的两个观测值或使用滞后来比较当前观测值和上一个观测值。

      data have;
      length datetime $23.;
      input datetime $ type ;
      datalines;
      ddmmyy:10:30:00  0
      ddmmyy:10:31:00  0
      ddmmyy:10:32:00  1
      ddmmyy:10:33:00  0
      ddmmyy:10:34:00  1
      ddmmyy:10:35:00  0
      ;
      run; 
      
      data want;
          merge have have(firstobs=2 keep=type rename=(type=_type));
          if max(type,_type) or max(type,lag(type)) ;
          drop _type;
      run;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-12
        • 1970-01-01
        • 1970-01-01
        • 2017-09-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多