我们在处理数据的时候,经常会遇到观测值(数据中,每一行叫一个观测值)有重复的情况;有些时候这些观测值是有差别的,而这些差别有可能要关注,也有可能不关注。
下面我们来看一下下图的数据,我截取了某调查数据的一小部分。第一列是Iid,第二列是调查时间,第三列是年龄,第四列是性别。
如果我们只看id,我们会发现这些数据存在重复项。观测值1.2.3(第1.2.3行)重复,id都是11004508,观测值4.5重复,id都是11004808,……
但如果我们看id,age,sex,我们发现这些数据并不存在重复。

例1.如果我们只想保留id相同观测值中的其中一行数据,也就是说观测值1.2.3只留其中一条,观测值4.5只留其中一条,我们直接用一下强制去重命令即可;
help duplicates 可以查看帮助文件,其格式如下:
duplicates drop varlist [if] [in] , force
在本例中,如下命令即可:
duplicates drop id, force / 强制去重id重复的样本
执行以上命令后,结果如下,11个观测值只留下6个id没有重复的,以id为11004508的为例,留下的是年龄为94岁,sex为female的那一个观测值。

例2. 有时候,我们可能需要根据两个或多个变量去重,也就是只要我们考虑的那两个变量都不一样,就可以去掉。
倘若我告诉你,图1中的id为11004508的观测值是夫妻,女性经过了两轮调查,因此她的年龄不一样。而我们在处理数据的时候只需要id和age不重复的样本,我们只需修改下例2命令即可,结果如下,保留了8个观测值,id11004508的样本保留了女性1例,在第一行,男性1例,在第八行:
duplicates drop id sex, force / 强制去重id 和age 重复的样本
倘若需要对多个变量去重,加上其他变量即可。

例3,我们的第三任务是,对同一个id,保留年龄较小的一次调查(涉及到id、age两个变量,不涉及sex),这样的处理更加复杂,可以通过以下步骤完成。
(1)根据id和age排序数据,id在前age在后,可以先根据id排序,再根据age大小排序
(2)由于已根据id和age排序,可以根据根据id分组,产生顺序变量n,结果如下,可以看到,id为11004508的观测值后,年龄为94,97,97的顺序分别为1、2、3;

(3)保留n为1的观测值
sort id age /根据id 和 age 排序
by id: gen n = _n /以id为分组,产生顺序变量n
keep if n == 1 /保留n为1的观测值
结果如下,还剩7个观测值,都是年龄最小的:

例4. 我们继续加深难度,倘若我们要保留年龄最大的那个不重复样本该怎么办呢?
思考:排序有正序和逆序,但不管怎么排,只要是sort(gsort逆序)后的变量都是同一种排序方式,不能一个顺序一个逆序。有网友建议用 sort id -age的方式,也就是按age的相反数排序,但运行不成功,但这是一个很好地思考。我们先排序id,再排序age的相反数,这样,age大的就在前面了,因此,采用下列办法。
(1)产生新变量为age的相反数
(2)例1的方法
gen gage = 0-age / 产生age的相反数为gage
sort id gage /根据id 和 gage 排序

可以看到,这一次的排序,age大的在前面
by id: gen n = _n /以id为分组,产生顺序变量n
keep if n == 1 /保留n为1的观测值
继续去重,结果如下,留下的都是年龄较大的那一个;


本文介绍了如何在数据处理中处理重复观测值的问题,通过四个实例展示了不同情况下的去重策略。从单一变量去重到基于多个变量的条件去重,再到保留特定条件(如年龄最小或最大)的观测值,详细阐述了使用duplicatesdrop命令进行数据清洗的过程。此外,还讨论了如何根据实际需求选择合适的去重条件,以确保数据的准确性和一致性。
1万+





