我们在处理数据的时候,经常会遇到观测值(数据中,每一行叫一个观测值)有重复的情况;有些时候这些观测值是有差别的,而这些差别有可能要关注,也有可能不关注。
下面我们来看一下下图的数据,我截取了某调查数据的一小部分。第一列是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的观测值
继续去重,结果如下,留下的都是年龄较大的那一个;