2015-02-04 2 views
0

Мой вопрос касается обнаружения дубликатов. Скажем, у меня есть следующие данные:Обнаружение дубликатов

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 дублируется, потому что Джо появляется только в пределах posA. Я только хочу найти, что 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 не вызывает проблем, если это дает решение.

Есть ли способ сделать это?

ответ

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] 
+0

Спасибо! Рад получить ответ от мирового эксперта по этому вопросу. – bill999