SAS - 在同一数据集的不同 ID 变量中逐行比较并删除所有重复项
SAS - Row by row Comparison within different ID Variables of Same Dataset and delete ALL Duplicates
我需要一些帮助来尝试比较不同 ID 变量组中的行,所有这些都在一个数据集中。
也就是说,如果在两个或多个 ID 组中有 any 重复观察,那么我想完全删除观察。
我想识别不同组的行之间的任何重复项并完全删除观察。
例如:
ID Value
1 A
1 B
1 C
1 D
1 D
2 A
2 C
3 A
3 Z
3 B
我想要的输出是:
ID Value
1 D
3 Z
我在网上广泛查看,并尝试了一些东西。我想我可以用一个标志标记重复项,然后根据该标志删除。
举报代码为:
data have;
set want;
flag = first.ID ne last.ID;
run;
这在某些情况下有效,但我还在标记的 相同 值组中找到了重复项。
因此删除了第一个观察结果:
ID Value
3 Z
我也试过:
data have;
set want;
flag = first.ID ne last.ID and first.value ne last.value;
run;
但这根本没有标记任何重复项。
如有任何帮助,我将不胜感激。
如果需要任何其他信息,请告诉我。
谢谢。
我认为你应该做的是:
data want;
set have;
by ID value;
if not first.value then flag = 1;
else flag = 0;
run;
这基本上会标记除给定 ID 的第一个值之外的所有出现的值。
我也改变了想要并假设你从你 have
创造你 want
的东西。我还假设 have
是按 ID 值顺序排序的。
此外,这只会在上面标记 1 D
。不是 3 Z
额外输入
你不能做一个排序来去掉重复项吗:
proc sort data = have out = want nodupkey dupout = not_wanted;
by ID value;
run;
这是我对需求的解读。
查找仅出现在 1 个 ID 中的值级别。
data have;
input ID Value:.;
cards;
1 A
1 B
1 C
1 D
1 D
2 A
2 C
3 A
3 Z
3 B
;;;;
proc print;
proc summary nway; /*Dedup*/
class id value;
output out=dedup(drop=_type_ rename=(_freq_=occr));
run;
proc print;
run;
proc summary nway;
class value;
output out=want(drop=_type_) idgroup(out[1](id)=) sum(occr)=;
run;
proc print;
where _freq_ eq 1;
run;
proc print;
run;
这是一种相当简单的方法:按值 + ID 进行排序和去重,然后仅保留具有仅出现在单个 ID 中的值的行。
data have;
input ID Value $;
cards;
1 A
1 B
1 C
1 D
1 D
2 A
2 C
3 A
3 Z
3 B
;
run;
proc sort data = have nodupkey;
by value ID;
run;
data want;
set have;
by value;
if first.value and last.value;
run;
proc sql 版本:
proc sql;
create table want as
select distinct ID, value from have
group by value
having count(distinct id) =1
order by id
;
quit;
稍微不同的方法可以使用散列对象来跟踪属于单个组的唯一值。
data have; input
ID Value:& .; datalines;
1 A
1 B
1 C
1 D
1 D
2 A
2 C
3 A
3 Z
3 B
run;
proc delete data=want;
proc ds2;
data _null_;
declare package hash values();
declare package hash discards();
declare double idhave;
method init();
values.keys([value]);
values.data([value ID]);
values.defineDone();
discards.keys([value]);
discards.defineDone();
end;
method run();
set have;
if discards.find() ne 0 then do;
idhave = id;
if values.find() eq 0 and id ne idhave then do;
values.remove();
discards.add();
end;
else
values.add();
end;
end;
method term();
values.output('want');
end;
enddata;
run;
quit;
%let syslast = want;
因此,如果您按 VALUE 级别(而不是按 ID 级别)处理观察结果,那么您只需要跟踪是否有任何 ID 与第一个不同。
data want ;
do until (last.value);
set have ;
by value ;
if first.value then first_id=id;
else if id ne first_id then remapped=1;
end;
if not remapped;
keep value id;
run;
我需要一些帮助来尝试比较不同 ID 变量组中的行,所有这些都在一个数据集中。
也就是说,如果在两个或多个 ID 组中有 any 重复观察,那么我想完全删除观察。
我想识别不同组的行之间的任何重复项并完全删除观察。
例如:
ID Value
1 A
1 B
1 C
1 D
1 D
2 A
2 C
3 A
3 Z
3 B
我想要的输出是:
ID Value
1 D
3 Z
我在网上广泛查看,并尝试了一些东西。我想我可以用一个标志标记重复项,然后根据该标志删除。
举报代码为:
data have;
set want;
flag = first.ID ne last.ID;
run;
这在某些情况下有效,但我还在标记的 相同 值组中找到了重复项。
因此删除了第一个观察结果:
ID Value
3 Z
我也试过:
data have;
set want;
flag = first.ID ne last.ID and first.value ne last.value;
run;
但这根本没有标记任何重复项。
如有任何帮助,我将不胜感激。 如果需要任何其他信息,请告诉我。
谢谢。
我认为你应该做的是:
data want;
set have;
by ID value;
if not first.value then flag = 1;
else flag = 0;
run;
这基本上会标记除给定 ID 的第一个值之外的所有出现的值。
我也改变了想要并假设你从你 have
创造你 want
的东西。我还假设 have
是按 ID 值顺序排序的。
此外,这只会在上面标记 1 D
。不是 3 Z
额外输入
你不能做一个排序来去掉重复项吗:
proc sort data = have out = want nodupkey dupout = not_wanted;
by ID value;
run;
这是我对需求的解读。 查找仅出现在 1 个 ID 中的值级别。
data have;
input ID Value:.;
cards;
1 A
1 B
1 C
1 D
1 D
2 A
2 C
3 A
3 Z
3 B
;;;;
proc print;
proc summary nway; /*Dedup*/
class id value;
output out=dedup(drop=_type_ rename=(_freq_=occr));
run;
proc print;
run;
proc summary nway;
class value;
output out=want(drop=_type_) idgroup(out[1](id)=) sum(occr)=;
run;
proc print;
where _freq_ eq 1;
run;
proc print;
run;
这是一种相当简单的方法:按值 + ID 进行排序和去重,然后仅保留具有仅出现在单个 ID 中的值的行。
data have;
input ID Value $;
cards;
1 A
1 B
1 C
1 D
1 D
2 A
2 C
3 A
3 Z
3 B
;
run;
proc sort data = have nodupkey;
by value ID;
run;
data want;
set have;
by value;
if first.value and last.value;
run;
proc sql 版本:
proc sql;
create table want as
select distinct ID, value from have
group by value
having count(distinct id) =1
order by id
;
quit;
稍微不同的方法可以使用散列对象来跟踪属于单个组的唯一值。
data have; input
ID Value:& .; datalines;
1 A
1 B
1 C
1 D
1 D
2 A
2 C
3 A
3 Z
3 B
run;
proc delete data=want;
proc ds2;
data _null_;
declare package hash values();
declare package hash discards();
declare double idhave;
method init();
values.keys([value]);
values.data([value ID]);
values.defineDone();
discards.keys([value]);
discards.defineDone();
end;
method run();
set have;
if discards.find() ne 0 then do;
idhave = id;
if values.find() eq 0 and id ne idhave then do;
values.remove();
discards.add();
end;
else
values.add();
end;
end;
method term();
values.output('want');
end;
enddata;
run;
quit;
%let syslast = want;
因此,如果您按 VALUE 级别(而不是按 ID 级别)处理观察结果,那么您只需要跟踪是否有任何 ID 与第一个不同。
data want ;
do until (last.value);
set have ;
by value ;
if first.value then first_id=id;
else if id ne first_id then remapped=1;
end;
if not remapped;
keep value id;
run;