假设我的数据集如下所示:
obs id1 id2
1 a 1
2 b 2
3 c 2
4 d 3
5 e 4
6 b 5
7 f 6
我想为此数据集创建一个唯一的 transitive id
变量。 id1
和id2
均用于识别个人。因此,如果个体X
与个体id1
具有相同的Y
或与个体id2
具有相同的Y
,则{{1 }}。
因此,在此示例中,预期的输出将如下所示:
X=Y
在这里,观察obs id1 id2 uniqid
1 a 1 1
2 b 2 2
3 c 2 2
4 d 3 3
5 e 4 4
6 b 5 2
7 f 6 5
具有6
“ b”,该b已被分配为单数id1
(通过观察2
),因此观察2
与观察值6
标识同一个人。
现在,比较观察值2
和3
,我们发现这些观察值既不共享6
也不共享id1
,但仍标识同一个人,因为它们都标识了与观察值id2
相同。
我目前在Stata工作,我想知道这样做的最佳方法是什么。我希望使用基于Stata的解决方案,但也希望了解R或Python解决方案。
答案 0 :(得分:2)
社区贡献的 Stata命令group_id
可以满足您的要求。
但是,它使不匹配的标识符保持不变:
clear
input obs str1 id1 id2
1 a 1
2 b 2
3 c 2
4 d 3
5 e 4
6 b 5
7 f 6
end
clonevar id = id2
group_id id, match(id1)
sort obs
list, separator(0)
+----------------------+
| obs id1 id2 id |
|----------------------|
1. | 1 a 1 1 |
2. | 2 b 2 2 |
3. | 3 c 2 2 |
4. | 4 d 3 3 |
5. | 5 e 4 4 |
6. | 6 b 5 2 |
7. | 7 f 6 6 |
+----------------------+
还有另一个例子可以证明确实如此:
clear
input obs str1 id1 id2
1 a 1
2 b 2
3 c 7
4 d 3
5 e 4
6 b 5
7 f 1
end
clonevar id = id2
group_id id, match(id1)
sort obs
list, separator(0)
+----------------------+
| obs id1 id2 id |
|----------------------|
1. | 1 a 1 1 |
2. | 2 b 2 2 |
3. | 3 c 7 7 |
4. | 4 d 3 3 |
5. | 5 e 4 4 |
6. | 6 b 5 2 |
7. | 7 f 1 1 |
+----------------------+
如果您想在比赛之后使用连续的标识符(即第一个示例中的5
而不是6
,第二个示例中的7
),则必须手动进行调整
答案 1 :(得分:2)
由社区贡献的group_twoway
(在SSC中可用)是您问题的直接解决方案。您应确保id1和id2具有相同的类型(数字或字符串),并且它们的范围内没有重叠值。下面的代码适用于您的示例。
ssc install group_twoway
gen id2_str = string(id2)
group_twoway id1 id2_str, gen(id)
Pearly解决方案(使用group_id
)又增加了一步,无需手动调整即可解决您的问题。
clonevar x = id1
group_id x, match(id2)
egen id = group(x)
如果您可能觉得这些软件包太“黑匣子”,那么下面的代码是满足您逻辑需求的...语言。
egen x0 = group(id1)
egen x1 = min(x0), by(id2)
local i=1
while r(N) <_N {
egen x`=`i'+1' = min(x`i'), by(x`=`i'-1')
count if x`i++' == x`i'
}
egen id = group(x`i')
drop x*