【发布时间】:2011-07-23 16:43:26
【问题描述】:
我正在尝试分析来自明尼苏达大学 IPUMS 数据集的数据,以获取 R 中的 1990 US census。我正在使用survey 包,因为数据是weighted。仅获取家庭数据(并忽略人员变量以保持简单),我正在尝试计算 hhincome (household income) 的平均值。为此,我使用svydesign() 函数和以下代码创建了一个调查设计对象:
> require(foreign)
> ipums.household <- read.dta("/path/to/stata_export.dta")
> ipums.household[ipums.household$hhincome==9999999, "hhincome"] <- NA # Fix missing
> ipums.hh.design <- svydesign(id=~1, weights=~hhwt, data=ipums.household)
> svymean(ipums.household$hhincome, ipums.hh.design, na.rm=TRUE)
mean SE
[1,] 37029 17.365
到目前为止一切顺利。但是,如果我在 Stata(使用 code meant for a different portion of the same dataset)中尝试相同的计算,则会得到不同的标准错误:
use "C:\I\Hate\Backslashes\stata_export.dta"
replace hhincome = . if hhincome == 9999999
(933734 real changes made, 933734 to missing)
mean hhincome [fweight = hhwt] # The code from the link above.
Mean estimation Number of obs = 91746420
--------------------------------------------------------------
| Mean Std. Err. [95% Conf. Interval]
-------------+------------------------------------------------
hhincome | 37028.99 3.542749 37022.05 37035.94
--------------------------------------------------------------
而且,看看另一种给这只猫剥皮的方法,survey 的作者,this suggestion 用于频率加权:
expanded.data<-as.data.frame(lapply(compressed.data,
function(x) rep(x,compressed.data$weights)))
但是,我似乎无法让这段代码工作:
> hh.dataframe <- data.frame(ipums.household$hhincome, ipums.household$hhwt)
> expanded.hh.dataframe <- as.data.frame(lapply(hh.dataframe, function(x) rep(x, hh.dataframe$hhwt)))
Error in rep(x, hh.dataframe$hhwt) : invalid 'times' argument
我似乎无法修复。这可能与this issue有关。
总之:
- 为什么我在
Stata和R中得不到相同的答案? - 哪一个是对的(或者我在这两种情况下都做错了什么)?
- 假设我的
rep()解决方案有效,那会复制Stata的结果吗? -
正确的方法是什么?如果答案允许我使用
plyr包进行任意计算,而不是仅限于在survey(svymean()、svyglm()等)中实现的函数,则表示敬意
更新
因此,在我在这里和通过电子邮件从 IPUMS 收到的出色帮助之后,我正在使用以下代码来正确处理调查权重。我在这里描述以防其他人将来遇到此问题。
初始状态准备
由于 IPUMS 目前没有发布用于将数据导入 R 的脚本,因此您需要从 Stata、@987654351 开始@ 或 SPSS。我现在会坚持使用 Stata。首先从 IPUMS 运行导入脚本。然后在继续添加以下变量之前:
generate strata = statefip*100000 + puma
这将为 240001 形式的每个 PUMA 创建一个唯一整数,前两位数字作为州 fip 代码(在马里兰州为 24),后四位 PUMA id 在每个国家基础。如果您打算使用 R,您可能还会发现运行它也很有帮助
generate statefip_num = statefip * 1
这将创建一个没有标签的附加变量,因为将 .dta 文件导入 R 会应用标签并丢失基础整数。
Stata 和svyset
正如 Keith 所解释的,调查抽样由 Stata 通过调用 svyset 来处理。
对于我现在使用的个人层面分析:
svyset serial [pweight=perwt], strata(strata)
这将权重设置为perwt,对我们在上面创建的变量进行分层,并使用家庭serial 数字来说明聚类。如果我们使用多年,我们可能想尝试
generate double yearserial = year*100000000 + serial
还要考虑纵向聚类。
对于家庭层面的分析(没有年份):
svyset serial [pweight=hhwt], strata(strata)
应该是不言自明的(尽管我认为在这种情况下连续剧实际上是多余的)。将 serial 替换为 yearserial 将考虑时间序列。
在R
假设您要导入带有上述附加 strata 变量的 .dta 文件并在单个字母处进行分析:
require(foreign)
ipums <- read.dta('/path/to/data.dta')
require(survey)
ipums.design <- svydesign(id=~serial, strata=~strata, data=ipums, weights=perwt)
或者在家庭层面:
ipums.hh.design <- svydesign(id=~serial, strata=~strata, data=ipums, weights=hhwt)
希望有人觉得这很有帮助,非常感谢来自 IPUMS 的 Dwin、Keith 和 Brandon。
【问题讨论】:
-
非常感谢,这可能非常有用。当我第一次尝试解决它时,我发现 1990 年的人口普查并不那么令人生畏。恼人的是他们似乎重做了所有的人口普查区,所以我没有明显的方法来创建时间序列:(