Arrays 在SAS中设置阵列中的条件

Arrays 在SAS中设置阵列中的条件,arrays,count,sas,Arrays,Count,Sas,我有一组数据如下所示: ID Status31Jan2007 Status28Jan2007 Status31Mar2007 001 0 0 002 1 0 0 003 1 1 0 ID Flag1 Flag2

我有一组数据如下所示:

ID  Status31Jan2007 Status28Jan2007 Status31Mar2007
001                        0               0             
002        1               0               0
003        1               1               0
ID       Flag1           Flag2           Flag3 
001        N               N               N            
002        Y               N               N
003        Y               Y               N
我的Statusddmmyyyy字段为“0”或“1”,持续118个月。(在这里,我只有三个月的时间作为样本)

我希望得到如下结果:

ID  Status31Jan2007 Status28Jan2007 Status31Mar2007
001                        0               0             
002        1               0               0
003        1               1               0
ID       Flag1           Flag2           Flag3 
001        N               N               N            
002        Y               N               N
003        Y               Y               N
逻辑是,如果在Status31Jan2007=1,并且在接下来的两个月内,状态字段计数为0>0,然后将其标记为“Y”。否则,N

意思是, 如果我的ID为001,并且截至2007年1月31日的状态,该值丢失,则我会在Flag1下将其标记为“N”。 接下来的一个月,Status28Feb2007,值为0,我会在Flag2下自动将其标记为“N”。这适用于下个月

查看ID 002,2007年1月31日的状态为1。两个月后,我有两个0值。“0”值的计数大于0。因此,我在Flag1下将其标记为“Y”。 但在2007年2月28日的状态下,它是0。它不符合标准,因此我在Flag2下将其标记为“N”

只要在现场,我需要的状态是1,然后只有我继续研究接下来的两个月

得到结果后,如何计算每个字段下的标志N和Y的数量

        Count1           Count2          Count3
N          1               2               3 
Y          2               1               0

非常感谢您的帮助,因为我是SAS的新手。谢谢。

这只在列名按日历顺序排列时有效

使用
ARRAY
语句按索引组织并访问变量,从而轻松处理[index+1]和[index+2]检查逻辑指示。在分配标志值时,还可以使用临时数组来维护计数;在最后一行,计数被输出到一个单独的表中

注意:对于0或1的状态变量,可以使用
SUM
计算1的计数。当两个状态变量中的任何一个为0时,两个状态变量之和将小于2

* simulate some data;
data prelim;
  do id = 1 to 20;
    do date = '01jan07'd by 1 until(intck('month', '01jan07'd, date) >= 117);
      date = intnx('month', date, 1) - 1;
      status = ranuni(123) < 0.45;
      if date = '31jan07'd and mod(id,5) = 1 then status = .;
      output;
    end;
  end;
  format date date9.;
run;

* change the shape of simulated data to match the question;
proc transpose data=prelim prefix=Status out=have(drop=_name_);
  by id;
  var status;
  id date;
run;

* process the problem shaped data;    
data
  want (keep=id status: flag:)
  want_count (keep=flag_value count:);
;
  set have end=lastid;

  retain sentinel1 sentinel2 0;

  array status status: sentinel1 sentinel2;  * map all the Status* variables to an array named status;
  array flag [118] $1 ; * automatically creates 118 new variables flag1 to flag118;
  array yfreq [118] _temporary_ (118*0); * temporary arrays initialized to 0;
  array nfreq [118] _temporary_ (118*0);

  * process each month status, -2 because of the sentinels ;
  do i = 1 to dim(status)-2;

    * assign flag according to the logic, some cases require a 2-month look ahead;
    select;
      when ( status(i) = . ) flag(i) = 'N';
      when ( status(i) = 0 ) flag(i) = 'N';
      when ( status(i) = 1 
             and sum(status(i+1),status(i+2)) < 2 ) flag(i) = 'Y';  * SUM trick;
      otherwise
        flag(i) = 'N';
    end;

    * track frequencies of flags assigned;
    if flag(i) = 'N'
      then nfreq(i)+1;
      else yfreq(i)+1;
  end;

  output want;

  if lastid then do;
    * all flags for all ids have been binned for frequency;
    * output the freqs to a count data set;
    length flag_value $1;
    array freq count1-count118;
    flag_value = 'N'; do i = 1 to dim(nfreq); freq(i) = nfreq(i); end; output want_count;
    flag_value = 'Y'; do i = 1 to dim(yfreq); freq(i) = yfreq(i); end; output want_count;
  end;
run;
*模拟一些数据;
数据预校准;
do id=1至20;
执行日期='07年1月1日,直到(intck('month','07年1月1日,日期)>=117);
日期=intnx('month',date,1)-1;
状态=拉努尼(123)<0.45;
如果日期为'2007年1月31日'd,且日期(id,5)=1,则状态为。;
产出;
结束;
结束;
格式化日期9。;
跑
*改变模拟数据的形状以匹配问题;
proc transpose data=prelim prefix=Status out=have(drop=\u name\uu);
按身份证;
var状态;
身份证日期;
跑
*处理问题型数据;
数据
想要(保留=id状态:标志:)
想要计数(保持=标志值计数:);
;
设置have end=lastid;
保留哨兵1哨兵2 0;
阵列状态:Sentine1 sentinel2;*将所有Status*变量映射到名为Status的数组;
数组标志[118]$1;*自动创建118个新变量flag1到flag118;
数组yfreq[118]u临时_u118*0)*临时数组初始化为0;
数组nfreq[118]\u临时(118*0);
*处理每月状态,-2因为哨兵;
do i=1至变光(状态)-2;
*根据逻辑分配标志,有些情况需要提前2个月;
选择;
当(状态(i)=)标志(i)=‘N’时;
当(状态(i)=0)标志(i)=“N”时;
当(状态(i)=1时
和和(状态(i+1),状态(i+2))<2)标志(i)=‘Y’;*求和技巧;
否则
旗帜(i)=‘N’;
结束;
*跟踪指定旗帜的频率;
如果标志(i)=‘N’
然后nfreq(i)+1;
其他yfreq(i)+1;
结束;
产出需求;
如果是lastid,那么就这样做;
*所有ID的所有标志都已为频率装箱;
*将频率输出到计数数据集;
长度标志_值$1;
数组频率count1-count118;
标志_值='N';do i=1至dim(nfreq);频率(i)=nfreq(i);结束;输出要计数;
标志_值='Y';do i=1至dim(yfreq);频率(i)=yfreq(i);结束;输出要计数;
结束;
跑

我对逻辑有点不清楚,您希望每列的值是否取决于接下来两列中的值,如果是这种情况,那么最后两列将如何计算。也许可以解释一下您所显示的想要的值是如何计算的,例如,为什么在第一次观察中
Flag1
=N等等。我已经做了进一步的解释。希望它更清楚!:)第一列的值取决于以下两列的值。第二列将取决于接下来的两列,依此类推。谢谢。因此,据我所知,如果当前列为
1
,您只需要查看下两列。两个问题:(1)最后两列的逻辑是什么,因为你不能向前看两列?(2) 列名是否有模式?如果有,那么模式是什么?为了回答您的问题,(1)对于第二列,我将看最后一列。在最后一篇专栏文章中,我希望我的结果被标记为“N”,因为我不能再向前看了。(2) 对于我当前的数据集,我的列名仅为Status31Jan2007-Status31Oct2016。如果方便的话,我可以将其重命名为Status1-Status118。对于我的输出,它将使用不同的名称,所以可能是Flag1-Flag118。这就是你说的模式吗?