我的问题是检测重复。说我有以下数据:
clear all
input str2 pos str10 name
A Joe
A Joe
B Frank
C Mike
C Ted
D Mike
D Mike
E Bill
F Bill
end
如果我想检测所有重复的名称,我只需输入:
duplicates tag name, gen(flag)
这给了我:
pos name flag
A Joe 1
A Joe 1
B Frank 0
C Mike 2
C Ted 0
D Mike 2
D Mike 2
E Bill 1
F Bill 1
很棒 - 它表示Joe
,Mike
和Bill
是重复的。
但是,我想说我不想在pos
中包含任何重复的副本。换句话说,我不希望发现Joe
重复,因为Joe只出现在pos
A
中。我只想知道Mike
和Bill
是重复的。 (虽然Mike
内的D
重复,但他也会显示在C
中,因此他出现在多个pos
中。)
换句话说,我想:
pos name flag
A Joe 0
A Joe 0
B Frank 0
C Mike 1
C Ted 0
D Mike 1
D Mike 1
E Bill 1
F Bill 1
请注意,此处Mike
仅flag
代替1
2
。这是因为我将Mike
中的D
视为只出现一次而不是两次。如果解决方案产生此问题,则2
代替1
不会有问题。
有办法做到这一点吗?
答案 0 :(得分:2)
这不再是duplicates
特定意义上的重复问题。 (免责声明:我最初写的。)
您只想知道给定名称是否出现在不同的组中。该问题会在各个地方进行审核,例如here。
一种方法是将name
和pos
的每个不同的联合事件标记一次,然后计算群组。
clear
input str1 pos str5 name flag
A Joe 1
A Joe 1
B Frank 0
C Mike 2
C Ted 0
D Mike 2
D Mike 2
E Bill 1
F Bill 1
end
egen tag = tag(name pos)
egen npos = total(tag), by(name)
list , sepby(pos)
+---------------------------------+
| pos name flag tag npos |
|---------------------------------|
1. | A Joe 1 1 1 |
2. | A Joe 1 0 1 |
|---------------------------------|
3. | B Frank 0 1 1 |
|---------------------------------|
4. | C Mike 2 1 2 |
5. | C Ted 0 1 1 |
|---------------------------------|
6. | D Mike 2 1 2 |
7. | D Mike 2 0 2 |
|---------------------------------|
8. | E Bill 1 1 2 |
|---------------------------------|
9. | F Bill 1 1 2 |
+---------------------------------+
有些人可能希望看到没有egen
的解决方案:
bysort name pos: gen tag = _n == 1
by name: gen npos = sum(tag)
by name replace npos = npos[_N]
只需使用一个新变量即可重写:
bysort name pos: gen npos = _n == 1
by name: replace npos = sum(npos)
by name: replace npos = npos[_N]