我想要类似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重新排序后进行比较,但这实际上只是在撤消我刚才所做的事情。
如果有任何更好的建议,我将不胜感激。
答案 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-作为主要工具,可以通过以下方式为您解决问题:
创建变量(C2inListC1)以检查Country2是否在其中 Country1的列表
如果一个Country2在Country1的列表中,则其valC2_g2将具有对应于Country1的valC1_g2的(最大值)值。之所以提到(max),是因为到目前为止,到目前为止,尚不确定每个Country1是否应具有相同的valC1_g2。
创建一个变量(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"
}