SAS删除组内满足条件的观察
SAS to delete observations that meet condition within group
我想删除 Have
数据集中满足以下所有条件的记录。 ID_num这里代表ID
字段的3位数字部分
- ID = Mxxx
- 类型 = 血型
- 位于以下任何记录之前在每个组中(ID_num,药物)。
- ID=Mxxx 和类型=milk
- ID=Infxxx
下面是 Have
和所需的输出。
data have;
input ID $ Type $ Drug $;
cards;
M001 blood A
M001 blood A
M001 blood A
M001 blood B
M001 blood B
M001 milk B
M001 blood C
M001 blood C
M002 blood A
M002 blood A
Inf002 blood A
M002 blood A
M002 blood B
M002 milk C
Inf003 blood B
M003 blood B
;
run;
data want;
input ID $ Type $ Drug $;
cards;
M001 milk B
Inf002 blood A
M002 blood A
M002 milk C
Inf003 blood B
M003 blood B
;
run;
例如inf002药物A观察下的M002(血液,药物A),因为它出现在同一药物组的婴儿样本之后。但上面的两个 M002(血液,A)观察结果应该被删除,因为它们发生在同一药物组的第一个婴儿样本之前。相反,M001(牛奶,B)之后的两个M001(血液,C)观察应删除,因为药物组不同。
编辑:分组依据(gp
、Drug
)。
键
使用SAS regex(此处为prxmatch(patt, var)
)提取ID
分组数(代码中为gp
)。
可以检查保留条件 row-by-row 同时也可以按 (gp
, Drug
) 分组。 gp
中的更改由 FIRST.drug
标识。
- 在使用
BY
语句之前,必须对数据集进行排序。由于 SAS 排序稳定,原始排序不会中断。
- 可以通过在正则表达式解析阶段记录
_n_
来跟踪原始顺序。
代码
* "have" is in your post;
data tmp;
set have;
pos = prxmatch('(\d{3})', ID);
gp = substr(ID, pos, pos+2); * group number;
mi = substr(ID, 1, 1); * mother or infant;
n = _n_; * keep track of the original ordering;
drop pos;
run;
proc sort data=tmp out=tmp;
by gp drug;
run;
data want(drop=flag_keep gp mi);
set tmp;
by gp drug;
* state variables;
retain flag_keep 0;
if FIRST.drug then flag_keep = 0;
* mark keep;
if (flag_keep = 1) or (mi = "I") or ((mi = "M") and (Type = "milk"))
then flag_keep = 1;
if flag_keep = 1 then output;
run;
proc sort data=want out=want;
by n;
run;
结果:为清楚起见,显示了原始行号 n
。
ID Type Drug n
1 M001 milk B 6
2 Inf002 blood A 11
3 M002 blood A 12
4 M002 milk C 14
5 Inf003 blood B 15
6 M003 blood B 16
我想删除 Have
数据集中满足以下所有条件的记录。 ID_num这里代表ID
字段的3位数字部分
- ID = Mxxx
- 类型 = 血型
- 位于以下任何记录之前在每个组中(ID_num,药物)。
- ID=Mxxx 和类型=milk
- ID=Infxxx
下面是 Have
和所需的输出。
data have;
input ID $ Type $ Drug $;
cards;
M001 blood A
M001 blood A
M001 blood A
M001 blood B
M001 blood B
M001 milk B
M001 blood C
M001 blood C
M002 blood A
M002 blood A
Inf002 blood A
M002 blood A
M002 blood B
M002 milk C
Inf003 blood B
M003 blood B
;
run;
data want;
input ID $ Type $ Drug $;
cards;
M001 milk B
Inf002 blood A
M002 blood A
M002 milk C
Inf003 blood B
M003 blood B
;
run;
例如inf002药物A观察下的M002(血液,药物A),因为它出现在同一药物组的婴儿样本之后。但上面的两个 M002(血液,A)观察结果应该被删除,因为它们发生在同一药物组的第一个婴儿样本之前。相反,M001(牛奶,B)之后的两个M001(血液,C)观察应删除,因为药物组不同。
编辑:分组依据(gp
、Drug
)。
键
使用SAS regex(此处为
prxmatch(patt, var)
)提取ID
分组数(代码中为gp
)。可以检查保留条件 row-by-row 同时也可以按 (
gp
,Drug
) 分组。gp
中的更改由FIRST.drug
标识。- 在使用
BY
语句之前,必须对数据集进行排序。由于 SAS 排序稳定,原始排序不会中断。 - 可以通过在正则表达式解析阶段记录
_n_
来跟踪原始顺序。
- 在使用
代码
* "have" is in your post;
data tmp;
set have;
pos = prxmatch('(\d{3})', ID);
gp = substr(ID, pos, pos+2); * group number;
mi = substr(ID, 1, 1); * mother or infant;
n = _n_; * keep track of the original ordering;
drop pos;
run;
proc sort data=tmp out=tmp;
by gp drug;
run;
data want(drop=flag_keep gp mi);
set tmp;
by gp drug;
* state variables;
retain flag_keep 0;
if FIRST.drug then flag_keep = 0;
* mark keep;
if (flag_keep = 1) or (mi = "I") or ((mi = "M") and (Type = "milk"))
then flag_keep = 1;
if flag_keep = 1 then output;
run;
proc sort data=want out=want;
by n;
run;
结果:为清楚起见,显示了原始行号 n
。
ID Type Drug n
1 M001 milk B 6
2 Inf002 blood A 11
3 M002 blood A 12
4 M002 milk C 14
5 Inf003 blood B 15
6 M003 blood B 16