检查一个变量的每个值是否与另一个变量的任何值匹配

时间:2019-01-11 20:36:25

标签: merge stata

我想要类似egen newvar = anymatch(oldvar1), values(oldvar2)的东西。这将创建一个指标变量,该变量显示oldvar2中的特定值是否包含在oldvar1中的任何位置。除了anymatch的AFAIK之外,values仅接受integer numlist

这将有很多用途,但这是我的第一个示例:我有一个大的国家/地区对数据集。我有一个Country1具有特定属性的子集。我想确定与子集的任何成员匹配的Country2。

让我看看是否可以制作一个玩具示例:

     +--------------------------------------------------+
     | pair   Country1   value_C1   Country2   valC1_g2 |
     |--------------------------------------------------|
  1. |   AB          A          1          B          0 |
  2. |   AC          A          2          C          0 |
  3. |   BA          B          3          A          1 |
  4. |   BC          B          4          C          1 |
  5. |   CA          C          5          A          1 |
     |--------------------------------------------------|
  6. |   CB          C          6          B          1 |
     +--------------------------------------------------+

value_C1变量与Country1的属性有关。变量valC1_g2表示value_C1>2。我想要一个变量,该变量指示Country2中的每个特定变量在Country1 if valC1_g2列表中是否有匹配项。

这似乎不是一个罕见的问题,但是除了这个researchgate主题之外,我找不到直接解决它的东西。

这可以通过合并来完成:

preserve // saves current data
tempfile localdata // initialize a temporary new dataset
  keep Country1 valC1_g2 // subsetting allows re-ordering of just these variables
  rename (Country1 valC1_g2) (Country2 valC2_g2) // renaming to match the target
  sort Country2 // this just facilitates the 1:1 merge
  save `localdata'
restore // bring back original data

sort Country2 
merge  Country2 using `localdata' // this re-orders the subset to align with Country2 
  sort Country1 pair  // this resets the dataset to the original order

list, abbreviate(10) separator(0)

     +-------------------------------------------------------------+
     | pair   value_C1   Country1   Country2   valC1_g2   valC2_g2 |
     |-------------------------------------------------------------|
  1. |   AB          1          A          B          0          1 |
  2. |   AC          2          A          C          0          1 |
  3. |   BA          3          B          A          1          0 |
  4. |   BC          4          B          C          1          1 |
  5. |   CA          5          C          A          1          0 |
  6. |   CB          6          C          B          1          1 |
     +-------------------------------------------------------------+

我看到这种方法有两个问题。

首先,您将看到我的merge语法使用旧语法,因为Country2不能唯一标识我的数据。 (我想这意味着我正在使用新语法执行m:m?merge的文档说这是不行的。)pair变量起着这个作用,但是我不能成对合并,否则我将无法得到我需要的重新排序。也许我太担心了?

第二,如何检查它是否有效?之后,我想比较Country1和Country2中的国家/地区ID,以查看它们是否具有相同的值集。 compare不起作用,因为这些值未按行排列。我唯一想做的就是再次使用merge重新排序后进行比较,但这实际上只是在撤消我刚才所做的事情。

如果有任何更好的建议,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

  

一个变量,指示如果valC1_g2 ,Country2是否在 Country1的列表中。

对您的描述并不清楚,可能会导致不同的理解:

  • 在对应的观察值(对)中,国家/地区1对的解释为valC1_g2 = 1 (就像Pearly Spencer的代码一样,它优雅且“令人愉快”),如果您可能熟悉mata)。

  • 与此同时,其他人可能会认为它是相关观察值(对)中的 Country2与某处的Country1相同,并且 Country1 具有其(最大)valC1_g2 = 1 。请注意,这里提到的(max)是因为您的样本很小,因此无法假设任何Country1在任何观测值中都应具有相同的valC1_g2。

对我来说,您的尝试代码意味着第二种理解。如果是这种情况,在代码中再增加1行可以为您提供帮助。实际上,还有其他一些方法(可能会更优雅),但是这种方法可以节省您的跟踪时间。

preserve
tempfile localdata
keep Country1 valC1_g2

*(Addedline)
collapse (max) valC1_g2 if valC1_g2, by(Country1)

rename (Country1 valC1_g2) (Country2 valC2_g2)
save `localdata'
restore
sort Country2

* (It is better to use the new merge syntax, despite your old one might work)
merge m:1 Country2 using `localdata', keep(master match) nogen

编辑。您的编辑版本可以使您更清楚地了解第二点的理解,从而确认了第二个理解。另一个提高透明度的建议是,不应将“后续部分” (比较2个国家/地区ID)与“第二部分” 放在同一行(选中第一部分的代码逻辑)。这是两个不同的问题。

下面的代码仍然使用 -merge-作为主要工具,可以通过以下方式为您解决问题:

  1. 创建变量(C2inListC1)以检查Country2是否在其中 Country1的列表

  2. 如果一个Country2在Country1的列表中,则其valC2_g2将具有对应于Country1的valC1_g2的(最大值)值。之所以提到(max),是因为到目前为止,到目前为止,尚不确定每个Country1是否应具有相同的valC1_g2。

  3. 创建一个变量(C1inListC2)以检查Country1是否在Country2列表中。然后,您可以使用C2inListC1和C1inListC2的信息来检查Country1和Country2是否具有相同的值集。仅当“所有Country2都在Country1的列表中” “所有Country1都在Country2的列表中”时,两者都相同。

请注意,尽管还有其他方法(在编码中可能更简洁或更优雅,尤其是对于创建C2inListC1而言),但 -merge-提供了非常清晰而直接的逻辑,似乎收集valC1_g2信息的最佳工具。它应该只在正确的逻辑上起作用。编码只不过是将逻辑本身转换为编码语言而已。

tempfile ListC1 ListC2

preserve
collapse (max) valC1_g2, by(Country1)
rename (Country1 valC1_g2) (Country2 valC2_g2)
save `ListC1', replace
restore

preserve
contract Country2
ren Country2 Country1
save `ListC2', replace
restore

merge m:1 Country2 using `ListC1', keep(master match) gen(C2inListC1)
merge m:1 Country1 using `ListC2', keep(master match) gen(C1inListC2) keepusing(Country1)

recode C2inListC1 C1inListC2 (3=1) (else=0)
label values C2inListC1 C1inListC2 none

count if C2inListC1==0 | C1inListC2==0
if r(N) == 0{
di "Country1 and Country2 have the same values set"
}
else {
di in red "Country1 and Country2 do NOT have the same values set"
}