如果变量在第一个实例中匹配 'n' 次未排序数据,则 SAS 分配二进制值

SAS assigning binary values if variable matches in first instance for 'n' times for unsorted data

希望你们都好。 DATA: 输入数据未排序,因此我使用散列 tables 来获取输入数据,进行一些迭代,排序然后输出。在任何迭代(使用 proc 排序)之前对原始 table 进行排序将是一项耗时的工作。如果没有其他选择,那么我将需要坐下来接受可怕的排序方法。

我想要的:我正在尝试枚举一个 table 变量 "answer" 与二进制值 (0/1) 如果变量 filter = "Y" 接下来 6 个月的观察同一个客户。在某些情况下,客户在某些月度观察中缺失,例如:客户 FG5151 在 2006 年 9 月和 10 月缺失。简而言之,如果变量过滤器 "Y",则应为同一客户的此观察和接下来 6 个月的观察分配变量"answer" 当量 1,否则 0。

data have;
input client $ dates date9. filter $;
datalines ;
Fg5151 28.Feb.06 N
Fg5151 31.Mar.06 N
Fg5151 30.Apr.06 N
Fg5151 31.May.06 Y
Fg5151 30.Jun.06 N
Fg5151 31.Jul.06 Y
Fg5151 31.Aug.06 N
Fg5151 30.Nov.06 N
Fg5151 31.Dec.06 N
Fg5151 01.Jan.07 N
A101 28.Feb.06 N
A101 31.Mar.06 N
A101 30.Apr.06 Y
A101 31.May.06 N
A101 30.Jun.06 N
A101 31.Jul.06 N
ABC123 31.Mar.06 N
;



data want;
input client $ dates date9. filter $ answer;
datalines ;
A101 28.Feb.06 N 0
A101 31.Mar.06 N 0
A101 30.Apr.06 Y 1
A101 31.May.06 N 1
A101 30.Jun.06 N 1
A101 31.Jul.06 N 1
ABC123 31.Mar.06 N 0
Fg5151 28.Feb.06 N 0
Fg5151 31.Mar.06 N 0
Fg5151 30.Apr.06 N 0
Fg5151 31.May.06 Y 1
Fg5151 30.Jun.06 N 1
Fg5151 31.Jul.06 Y 1
Fg5151 31.Aug.06 N 1
Fg5151 30.Nov.06 N 1
Fg5151 31.Dec.06 N 1
Fg5151 01.Jan.07 N 0
;

我已经写了哈希语句和数据步骤语句。我不知道如何解决这个问题:

/* data step approach */
data want;
  set have;
  retain answer c;
  if _n_=1 or lag(client) ne client then do;
    answer=0;
    c=0;
  end;
  if filter="Y" then do;
    call symput('xdate',dates);
    answer=1;
    c=1;
  end;
  else if answer=1 then c=c+1;
  if (intnx("month",dates,6,"same")) then do;
    answer=0;
    c=0;
  end;
run;
/* hash method approach */

data _null_;
    set have end=last;
    if _n_ = 1 then do;
        length newdate 8 answer 8 c 8;
        format newdate ddmmyy10.;
        declare hash hs(ordered: "a",hashexp: 9);
        hs.defineKey("client","dates");
        hs.defineData("client","dates","filter","answer","c");
        hs.defineDone();
    end;
    rc = hs.find();
    by client dates notsorted;
    if rc ne 0 then do;
        retain answer c;
        if _n_=1 or lag(client) ne client then do;
            answer=0;
            c=0;
        end;
        if filter="Y" then do;
            answer=1;
            c=1;
            hs.add();
        end;
        else if answer=1 then c=c+1;
        if (intnx("month",dates,6,"same")) then do;
            answer=0;
            c=0;
            hs.replace();
        end;
        hs.replace();
    end;
    if last eq 1 then do;
hs.output(dataset:
        "not_working");
    end;
run;

如有任何帮助,我们将不胜感激。 谢谢你。 问候, S

一个选项是PROC FORMAT。这里面有一个排序,但只有 filter='Y' 的人,所以希望这是最小的;如果您确信您的数据已按客户端分组(但未排序)(即,您可以跳过它,它不会删除任何内容),并且实际上无论如何都使用 m 选项(以避免担心碰撞)你可能可以跳过它。

这不一定是超快的,因为它使用 putn 函数而不是 put 语句。您将不得不了解它在更大的数据集上的表现。

这里的想法是我们构建一个格式,为每个记录定义 'Y' 的范围,并使用 hlo='o' 选项将剩余的 ragne 定义为 n

data for_fmt;
  set have;
  by client notsorted;
  if filter='Y' then do;
    start = dates;
    end = intnx('Month',dates,5,'s');
    hlo=' m';
    fmtname=cats(client,'F');
    label='Y';
    output;
  end;
  if last.client then do;
    fmtname=cats(client,'F');
    call missing(of start end);
    hlo='om';
    label='N';
    output;
  end;
run;

proc sort nodupkey data=for_fmt;
  by fmtname start;
run;


proc format cntlin=for_fmt;
quit;

data want;
  set have;
  answer = putn(dates,cats(client,'F'));
run;