如果在另一列的 (min, max) 日期之间,则 SAS 筛选器日期一列
SAS filter dates one column if between (min, max) dates of another column
我的数据集如下所示
ID
日期 1
日期 2
一个
2020 年 8 月 1 日
.
一个
2020 年 9 月 1 日
.
一个
2020 年 10 月 1 日
.
一个
2020 年 12 月 1 日
.
一个
.
2020 年 11 月 1 日
一个
.
2021 年 1 月 1 日
B
2020 年 3 月 1 日
.
B
2020 年 4 月 1 日
.
B
.
2020 年 1 月 1 日
C
2020 年 1 月 1 日
.
C
2020 年 3 月 1 日
.
C
.
2020 年 2 月 1 日
D
2020 年 1 月 1 日
.
D
2020 年 2 月 1 日
.
D
.
2020 年 3 月 1 日
日期 1 和日期 2 之间永远不会有任何交叉日期,并且每当一个字段被填充时,另一个字段为空。
我想为每个 ID 将 table 过滤到不同的类别中。最重要的是 Date2 在 Date1 字段中的某些日期之间(因此在 Date1 的最小值和最大值之间)。
因此,这会将 table 过滤为 ID A 01Nov2020,因为它介于 ID A 的最小值 (01Aug2020) 和最大值 (01Dec2020) 之间。以及 ID C 01Feb2020,因为这是 ID C 的最小值(01Jan2020)和最大值(01Mar2020)之间。
不太重要的是,我想过滤 table,其中 date2 在 Date1 的最小值之前(例如 ID B 01Jan2020)。然后是最终过滤的 table,其中 date2 在 Date1 的最小值之前(例如 ID D 01Mar2020 和 ID A 01Jan2021)。
困难的部分是它们没有按行对齐,因此必须跨数据集中的多行工作。我相信我可能需要使用 Array 函数,但我不确定。任何帮助将不胜感激。
PROC SQL 应该可以使这变得容易。它会自动将 MIN() 和 MAX() 值重新合并回所有详细信息行,以便您可以在计算每个 DATE2 值的状态时使用它们。
data have;
input id $ (date1 date2) (:date.);
format date1 date2 date9.;
row+1;
cards;
A 01Aug2020 .
A 01Sep2020 .
A 01Oct2020 .
A 01Dec2020 .
A . 01Nov2020
A . 01Jan2021
B 01Mar2020 .
B 01Apr2020 .
B . 01Jan2020
C 01Jan2020 .
C 01Mar2020 .
C . 01Feb2020
D 01Jan2020 .
D 01Feb2020 .
D . 01Mar2020
;
proc sql;
create table want as
select *
, case when missing(date2) then 'missing'
when (date2 between min(date1) and max(date1)) then '2 between 1'
when (date2 < min(date1)) then '2 less than 1'
when (date2 > max(date1)) then '2 greater than 1'
else 'unknown'
end as flag1
from have
group by id
order by id, row
;
quit;
结果:
Obs id date1 date2 row flag1
1 A 01AUG2020 . 1 missing
2 A 01SEP2020 . 2 missing
3 A 01OCT2020 . 3 missing
4 A 01DEC2020 . 4 missing
5 A . 01NOV2020 5 2 between 1
6 A . 01JAN2021 6 2 greater than 1
7 B 01MAR2020 . 7 missing
8 B 01APR2020 . 8 missing
9 B . 01JAN2020 9 2 less than 1
10 C 01JAN2020 . 10 missing
11 C 01MAR2020 . 11 missing
12 C . 01FEB2020 12 2 between 1
13 D 01JAN2020 . 13 missing
14 D 01FEB2020 . 14 missing
15 D . 01MAR2020 15 2 greater than 1
我的数据集如下所示
ID | 日期 1 | 日期 2 |
---|---|---|
一个 | 2020 年 8 月 1 日 | . |
一个 | 2020 年 9 月 1 日 | . |
一个 | 2020 年 10 月 1 日 | . |
一个 | 2020 年 12 月 1 日 | . |
一个 | . | 2020 年 11 月 1 日 |
一个 | . | 2021 年 1 月 1 日 |
B | 2020 年 3 月 1 日 | . |
B | 2020 年 4 月 1 日 | . |
B | . | 2020 年 1 月 1 日 |
C | 2020 年 1 月 1 日 | . |
C | 2020 年 3 月 1 日 | . |
C | . | 2020 年 2 月 1 日 |
D | 2020 年 1 月 1 日 | . |
D | 2020 年 2 月 1 日 | . |
D | . | 2020 年 3 月 1 日 |
日期 1 和日期 2 之间永远不会有任何交叉日期,并且每当一个字段被填充时,另一个字段为空。
我想为每个 ID 将 table 过滤到不同的类别中。最重要的是 Date2 在 Date1 字段中的某些日期之间(因此在 Date1 的最小值和最大值之间)。
因此,这会将 table 过滤为 ID A 01Nov2020,因为它介于 ID A 的最小值 (01Aug2020) 和最大值 (01Dec2020) 之间。以及 ID C 01Feb2020,因为这是 ID C 的最小值(01Jan2020)和最大值(01Mar2020)之间。
不太重要的是,我想过滤 table,其中 date2 在 Date1 的最小值之前(例如 ID B 01Jan2020)。然后是最终过滤的 table,其中 date2 在 Date1 的最小值之前(例如 ID D 01Mar2020 和 ID A 01Jan2021)。
困难的部分是它们没有按行对齐,因此必须跨数据集中的多行工作。我相信我可能需要使用 Array 函数,但我不确定。任何帮助将不胜感激。
PROC SQL 应该可以使这变得容易。它会自动将 MIN() 和 MAX() 值重新合并回所有详细信息行,以便您可以在计算每个 DATE2 值的状态时使用它们。
data have;
input id $ (date1 date2) (:date.);
format date1 date2 date9.;
row+1;
cards;
A 01Aug2020 .
A 01Sep2020 .
A 01Oct2020 .
A 01Dec2020 .
A . 01Nov2020
A . 01Jan2021
B 01Mar2020 .
B 01Apr2020 .
B . 01Jan2020
C 01Jan2020 .
C 01Mar2020 .
C . 01Feb2020
D 01Jan2020 .
D 01Feb2020 .
D . 01Mar2020
;
proc sql;
create table want as
select *
, case when missing(date2) then 'missing'
when (date2 between min(date1) and max(date1)) then '2 between 1'
when (date2 < min(date1)) then '2 less than 1'
when (date2 > max(date1)) then '2 greater than 1'
else 'unknown'
end as flag1
from have
group by id
order by id, row
;
quit;
结果:
Obs id date1 date2 row flag1
1 A 01AUG2020 . 1 missing
2 A 01SEP2020 . 2 missing
3 A 01OCT2020 . 3 missing
4 A 01DEC2020 . 4 missing
5 A . 01NOV2020 5 2 between 1
6 A . 01JAN2021 6 2 greater than 1
7 B 01MAR2020 . 7 missing
8 B 01APR2020 . 8 missing
9 B . 01JAN2020 9 2 less than 1
10 C 01JAN2020 . 10 missing
11 C 01MAR2020 . 11 missing
12 C . 01FEB2020 12 2 between 1
13 D 01JAN2020 . 13 missing
14 D 01FEB2020 . 14 missing
15 D . 01MAR2020 15 2 greater than 1