创建变量,逐步计算一个 ID 在一天内重复的次数

Create variable that counts progressively how many times an ID is repeated in a day

所以我有一个 table,每天有不同的日子和不同的时间,并且客户 ID 每天可以出现多次。

data Data1;
   infile datalines delimiter=',';
   input date :ddmmyy10. ID $ time :time8. $ ;
   format date ddmmyy10.;  
   format time time8.; 
datalines;
05/11/2020,1000,8:15:23
05/11/2020,1000,8:20:10
05/11/2020,1001,8:21:10
05/11/2020,1001,9:05:15
05/11/2020,1001,10:30:20
06/11/2020,1002,8:26:10
06/11/2020,1003,8:27:10
06/11/2020,1003,9:40:01
;

我想输出另一个名为“尝试”的列,它看起来像这样:

data Data1;
   infile datalines delimiter=',';
   input date :ddmmyy10. ID $ time :time8. $ Attempt;
   format date ddmmyy10.;  
   format time time8.; 
datalines;
05/11/2020,1000,8:15:23,1
05/11/2020,1000,8:20:10,2
05/11/2020,1001,8:21:10,1
05/11/2020,1001,9:05:15,2
05/11/2020,1001,10:30:20,3
06/11/2020,1002,8:26:10,1
06/11/2020,1003,8:27:10,1
06/11/2020,1003,9:40:01,2
06/11/2020,1000,10:20:10,1
06/11/2020,1000,11:20:10,2
06/11/2020,1000,12:20:10,3
06/11/2020,1000,13:20:10,3
;

如您所见,客户 1000 在 05/11 出现两次,在 06/11 出现 4 次,客户 1001 在 05/11 出现 3 次,客户 1002 在 06/11 出现一次,客户 1003 06/11出现2次

我还希望 3 是最大值,因此如果客户一天出现超过 3 次(例如 06/11 的客户 1000),则该值为 3。

我不介意使用 sas 语言或 proc sql,所以如果有人对这两者有任何想法,请告诉我

只用BY分组处理和一个保留变量。您可以使用 MIN() 函数将计数器上限设置为 3。

data Data1;
   infile datalines dsd;
   input date :ddmmyy. ID $ time :time. expect;
   format date ddmmyy10. time time8.; 
datalines;
05/11/2020,1000,8:15:23,1
05/11/2020,1000,8:20:10,2
05/11/2020,1001,8:21:10,1
05/11/2020,1001,9:05:15,2
05/11/2020,1001,10:30:20,3
06/11/2020,1000,10:20:10,1
06/11/2020,1000,11:20:10,2
06/11/2020,1000,12:20:10,3
06/11/2020,1000,13:20:10,3
06/11/2020,1002,8:26:10,1
06/11/2020,1003,8:27:10,1
06/11/2020,1003,9:40:01,2
;

data want;
  set data1;
  by date id ;
  retain attempt;
  if first.id then attempt=1;
  else attempt=min(3,attempt+1);
run;

注意:我重新排序了您的示例数据以避免需要添加 PROC SORT 步骤。如果您的真实数据集已分组但未排序,如您的示例所示,您可以在 BY 语句中添加 NOTSORTED 关键字,逻辑将起作用。

或者,您仍然可以考虑 proc sql 使用条件相关聚合查询:

data Data1;
   infile datalines delimiter=',';
   input date :ddmmyy10. ID $ time :time8. ;
   format date ddmmyy10.;  
   format time time8.; 
datalines;
05/11/2020,1000,8:15:23
05/11/2020,1000,8:20:10
05/11/2020,1001,8:21:10
05/11/2020,1001,9:05:15
05/11/2020,1001,10:30:20
06/11/2020,1002,8:26:10
06/11/2020,1003,8:27:10
06/11/2020,1003,9:40:01
06/11/2020,1000,10:20:10,1
06/11/2020,1000,11:20:10,2
06/11/2020,1000,12:20:10,3
06/11/2020,1000,13:20:10,3
;

proc sql;
    CREATE TABLE output AS
    SELECT d.date, d.ID, d.time
          , (SELECT CASE 
                         WHEN COUNT(*) > 3 
                         THEN 3 
                         ELSE COUNT(*) 
                    END FROM Data1 sub
             WHERE sub.ID = d.ID
               AND sub.date = d.date
               AND sub.time <= d.time
            ) AS attempts
    FROM Data1 d; 
quit;