根据现有ID创建唯一的可传递ID的最简单方法

时间:2019-04-20 19:02:31

标签: python r dataframe stata

假设我的数据集如下所示:

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变量。 id1id2均用于识别个人。因此,如果个体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标识同一个人。

现在,比较观察值23,我们发现这些观察值既不共享6也不共享id1,但仍标识同一个人,因为它们都标识了与观察值id2相同。

我目前在Stata工作,我想知道这样做的最佳方法是什么。我希望使用基于Stata的解决方案,但也希望了解R或Python解决方案。

2 个答案:

答案 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)

  1. 由社区贡献的group_twoway(在SSC中可用)是您问题的直接解决方案。您应确保id1和id2具有相同的类型(数字或字符串),并且它们的范围内没有重叠值。下面的代码适用于您的示例。

    ssc install group_twoway

    gen id2_str = string(id2)
    group_twoway id1 id2_str, gen(id)
    
  2. Pearly解决方案(使用group_id)又增加了一步,无需手动调整即可解决您的问题。

    clonevar x = id1 
    group_id x, match(id2)
    
    egen id = group(x)
    
  3. 如果您可能觉得这些软件包太“黑匣子”,那么下面的代码是满足您逻辑需求的...语言。

    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*