创建变量,逐步计算一个 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;
所以我有一个 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;