在 Stata 中生成相关变量
Generate correlated variables in Stata
我想在 Stata 中生成 5 个相关变量。四个具有特定均值和标准差的正态分布,一个服从伯努利概率为 0.60。
我尝试遵循 post 中给出的建议:
我的代码如下:
matrix C = (1, /// ///
2*sin(0.05*_pi/6), 1, ///
2*sin(-0.45*_pi/6), 2*sin(0.44*_pi/6), 1, ///
2*sin(0.22*_pi/6), 2*sin(0.33*_pi/6), 2*sin(-0.54*_pi/6), 1, ///
2*sin(0.45*_pi/6), 2*sin(0.32*_pi/6), 2*sin(-0.22*_pi/6), 2*sin(-0.13*_pi/6), 1)
matrix B = (40, 26, 13, 146, 0.35)
matrix A = (9, 11, 5, 2, 1)
corr2data var1 var2 var3 var4 var5, n(10000) corr(C) means(B) sds(A) cstorage(lower)
replace var1 = rnormal(var1)
replace var2 = rnormal(var2)
replace var3 = rnormal(var3)
replace var4 = rnormal(var4)
replace var5 = normal(var5)
replace var5 = rbinomial(1,var5)
从某种意义上说,我已经或多或少地得到了我想要的东西,即生成的变量所具有的值符合预期。
但是,我的做法正确吗?如果不是,您将如何修改代码以在科学合理的同时正确地给出所需的结果?
您的代码有几个问题。首先,相关矩阵的变换仅对生成 uniform 变量的特殊情况有用,但您需要相关的法线和二项式。其次,您不需要 re-generate var1-var4 和 rnormal
,因为 corr2data
已经为您完成了。第三,你的相关矩阵不是正(半)定的,所以代码不是为我写的运行。第四,您需要应用伯努利分布的逆 CDF 来模拟该分布的绘制(即链接 post 中的第 3 步),而不是使用 rbinomial()
.
这是一个包含两个法线和伯努利的简化示例:
clear
local p=0.6
matrix m = (10,0,0)
matrix sd = (5,1,1)
/* I am shooting for corr(n1,b)=0.5 and corr(n2,b)=0.75, so I exaggerate their correlations in the bottom row */
matrix c = ///
(1, ///
0.5, 1, ///
0.64, 0.95,1)
corr2data n1 n2 b, n(10000) corr(c) means(m) sds(sd) cstorage(lower)
/* Steps 2-3 for the one Bernoulli variable */
replace b = cond(normal(b)>=(1-`p'),1,0)
/* Check that we did things correctly */
corr, means
qnorm n1
qnorm n2
prtest b = `p'
一般来说,您必须研究法线和伯努利变量之间的相关性,才能让结果如您所愿。可以自动执行此搜索(或提出解析近似),但我没有时间对其进行编码或求解。
我想在 Stata 中生成 5 个相关变量。四个具有特定均值和标准差的正态分布,一个服从伯努利概率为 0.60。
我尝试遵循 post 中给出的建议:
我的代码如下:
matrix C = (1, /// ///
2*sin(0.05*_pi/6), 1, ///
2*sin(-0.45*_pi/6), 2*sin(0.44*_pi/6), 1, ///
2*sin(0.22*_pi/6), 2*sin(0.33*_pi/6), 2*sin(-0.54*_pi/6), 1, ///
2*sin(0.45*_pi/6), 2*sin(0.32*_pi/6), 2*sin(-0.22*_pi/6), 2*sin(-0.13*_pi/6), 1)
matrix B = (40, 26, 13, 146, 0.35)
matrix A = (9, 11, 5, 2, 1)
corr2data var1 var2 var3 var4 var5, n(10000) corr(C) means(B) sds(A) cstorage(lower)
replace var1 = rnormal(var1)
replace var2 = rnormal(var2)
replace var3 = rnormal(var3)
replace var4 = rnormal(var4)
replace var5 = normal(var5)
replace var5 = rbinomial(1,var5)
从某种意义上说,我已经或多或少地得到了我想要的东西,即生成的变量所具有的值符合预期。
但是,我的做法正确吗?如果不是,您将如何修改代码以在科学合理的同时正确地给出所需的结果?
您的代码有几个问题。首先,相关矩阵的变换仅对生成 uniform 变量的特殊情况有用,但您需要相关的法线和二项式。其次,您不需要 re-generate var1-var4 和 rnormal
,因为 corr2data
已经为您完成了。第三,你的相关矩阵不是正(半)定的,所以代码不是为我写的运行。第四,您需要应用伯努利分布的逆 CDF 来模拟该分布的绘制(即链接 post 中的第 3 步),而不是使用 rbinomial()
.
这是一个包含两个法线和伯努利的简化示例:
clear
local p=0.6
matrix m = (10,0,0)
matrix sd = (5,1,1)
/* I am shooting for corr(n1,b)=0.5 and corr(n2,b)=0.75, so I exaggerate their correlations in the bottom row */
matrix c = ///
(1, ///
0.5, 1, ///
0.64, 0.95,1)
corr2data n1 n2 b, n(10000) corr(c) means(m) sds(sd) cstorage(lower)
/* Steps 2-3 for the one Bernoulli variable */
replace b = cond(normal(b)>=(1-`p'),1,0)
/* Check that we did things correctly */
corr, means
qnorm n1
qnorm n2
prtest b = `p'
一般来说,您必须研究法线和伯努利变量之间的相关性,才能让结果如您所愿。可以自动执行此搜索(或提出解析近似),但我没有时间对其进行编码或求解。