在Stata中,我有一个包含两个变量的数据集:id
和var
,并说出1000个观察值。变量var
的类型为float
,并为所有观察值采用不同的值。我想只保留三个观察值,其中var是var的最小值,var的最大值或var的中值。
我目前这样做的方式:
summarize var, detail
local varmax = r(max)
local varmin = r(min)
local varmedian= r(p50)
keep if inlist(float(var),float(`varmax') , float(`varmedian'), float(`varmin'))
我遇到的问题是有时inlist
条件与其中一个值不匹配。例如。我最终得到两个观察而不是三个,例如一个有min和一个有max,但没有一个有中位数。我怀疑这与精度问题有关。如你所见,我试图将所有数字转换为浮点数,但这显然是不够的。
对我的解决方案或替代解决方案的任何修复都将非常感谢(如果可能的话,无需安装其他软件包),谢谢!
答案 0 :(得分:3)
这不是第一个精度问题。
当(1)值的数量是偶数并且(2)中值是两个不同的中心值的平均值时,这是不可避免的问题。然后,中位数本身不是数据集中的值,keep
将无法找到。
考虑数据集1,2,3,4。中值2.5不在数据中。这很常见;事实上,所有价值观都是预期的,甚至是观察数量。
可能会出现其他问题,因为最小值,中值和最大值中的两个或甚至三个可能彼此相等。这不是您目前的问题,但它可以与其他变量(例如指标变量)咬合。
精确度问题是可能的。
这是一种旨在避免所有这些困难的一般解决方案。
如果collapse
分钟,中位数。最大然后reshape
你可以避免这个问题。您将始终获得三个结果,即使它们在数值上相等和/或不存在于数据中。
在下面的简单示例中,仅需要标识符reshape
。在其他问题中,您可能希望collapse
使用by()
,然后您的标识符就绪。但是,在这种情况下,您不太可能想要reshape
。
. clear
. set obs 4
number of observations (_N) was 0, now 4
. gen y = _n
. collapse (min)ymin=y (max)ymax=y (median)ymedian=y
. gen id = _n
. reshape long y, i(id) j(statistic) string
(note: j = max median min)
Data wide -> long
-----------------------------------------------------------------------------
Number of obs. 1 -> 3
Number of variables 4 -> 3
j variable (3 values) -> statistic
xij variables:
ymax ymedian ymin -> y
-----------------------------------------------------------------------------
. list
+---------------------+
| id statis~c y |
|---------------------|
1. | 1 max 4 |
2. | 1 median 2.5 |
3. | 1 min 1 |
+---------------------+
所有这一切,只有三个观察结果的(很多?)数据集听起来很糟糕的数据管理策略。也许这是从一些更大的问题中提取的。
更新
这是保持精确3次观察的另一种方法。除了最小值和最大值之外,我们使用的规则是,当观察数为偶数时,我们保持低中位数",即中位数平均的两个值中的较低者,并且单个值是否则中位数。 (在斯蒂芬斯蒂格勒这个令人愉快的术语中,我们可以在第一种情况下谈论"喜剧演员和#34;)
. sysuse auto, clear
(1978 Automobile Data)
. sort mpg
. drop if missing(mpg)
(0 observations deleted)
. keep if inlist(_n, 1, cond(mod(_N, 2), ceil(_N/2), floor(_N/2)), _N)
(71 observations deleted)
. l mpg
+-----+
| mpg |
|-----|
1. | 12 |
2. | 20 |
3. | 41 |
+-----+
如果mod(_N, 2)
为奇数,则 _N
为1,如果_N
为偶数,则为{0}。 cond()
中的表达式如果观察的数量是奇数,则选择ceil(_N/2)
,如果是偶数,则选择floor(_N/2)
。