从 mlogit 收集 z 统计信息时矩阵意外缺失单元格
Matrix has unexpected missing cells when collecting z-statistics from mlogit
我希望 运行 一系列多项式 logits(每个感兴趣的协变量 600ish)并从每个中收集 z 统计量(我不关心这些记录的顺序)。
这些 mlogits 运行 在我的一小部分数据上(共享一个组 ID)。 mlogit 涉及不同数量的结果 (n),并且将从每个 mlogit 收集 (n - 1) z 个统计数据。每个 mlogit 都采用以下形式: y = a + _b*x + \epsilon 其中 y 可以取 2 到 9 个值(在我的数据中),尽管平均值是 3.7.
我认为困难在于将这些 z-stats 从 mlogit 中提取出来,因为我不知道如何直接调用 z-stats 矩阵。我的解决方案是从 e(V) 和 e(b) 矩阵构造 z-stats。对于 mlogit 的每次迭代,我构建了一个 z-stats 矩阵;然后我将其附加到之前的 z-stats 矩阵(从而构建所有计算的矩阵)。不幸的是,我的代码似乎没有正确执行此操作。
症状如下。矩阵 mat_covariate 包含许多缺失值(在我所做的故障排除中,超过一半的矩阵值缺失)。它还包括许多零(这是可能的,但不太可能——尤其是在这个比率下,大约 16%)。如所写,代码尚未抑制 mlogits I 运行,因此我可以返回并检查是什么使其进入矩阵。每个 mlogit 最多记录一个值,但这些值通常会记录多次。 40% 的 mlogits 没有任何记录。
相关循环如下:
local counter = 1
forvalues i = 1/`times' {
preserve
keep if group_id==`i'
foreach covariate in `covariates' {
if `counter' == 1 {
mlogit class `covariate'
sum outcomes_n, meanonly
local max = `r(max)'
local max_minus = `max' - 1
matrix mat_`covariate' = J(`max_minus',1,0)
forvalues j = 1/`max_minus' {
mat V = e(V)
mat b = e(b)
local z = b[1+2*(`j'-1),1] / ( V[1+2*(`j'-1),1+2*(`j'-1)] ) ^ (.5)
matrix mat_`covariate'[`j',1] = `z'
}
}
else {
mlogit class `covariate'
sum outcomes_n, meanonly
local max `r(max)'
local max_minus = `max' - 1
matrix mat_`covariate'_temp = J(`max_minus',1,0)
forvalues j = 1/`max_minus' {
mat V = e(V)
mat b = e(b)
local z = b[1+2*(`j'-1),1] / ( V[1+2*(`j'-1),1+2*(`j'-1)] ) ^ (.5)
matrix mat_`covariate'_temp[`j',1] = `z'
matrix mat_`covariate' = mat_`covariate' \ mat_`covariate'_temp
}
matrix mat_`covariate' = mat_`covariate' \ mat_`covariate'_temp
}
}
local counter = `counter'+1
restore
}
为什么我在循环中做了一些事情的一些原因。我相信这些东西有效,但它们不是我的第一直觉,我不清楚为什么我的第一直觉不起作用。如果有一个 simpler/more 优雅的方法来解决它们,那将是一个很好的奖励:
- 主要if/else(和计数器)是为了解决我无法在尚未定义矩阵时将其定义为自身函数的问题。
- 我为 max 定义了一个局部变量,为 (max-1) 定义了一个单独的变量。 forvalues 循环不接受 "1/(`max'-1) {" 我不确定为什么。
我创建了一些可用于重现此问题的示例数据。下面是一个 .do 文件的代码,它设置数据、循环的局部变量、上面的循环,并通过显示有问题的矩阵来演示症状:
clear all
version 14
//================== sample data: ==================
set obs 500
set seed 12345
gen id = _n
gen group_id = .
replace group_id = 1 if id <= 50
replace group_id = 2 if id <= 100 & missing(group_id)
replace group_id = 3 if id <= 150 & missing(group_id)
replace group_id = 4 if id <= 200 & missing(group_id)
replace group_id = 5 if id <= 250 & missing(group_id)
replace group_id = 6 if id <= 325 & missing(group_id)
replace group_id = 7 if id <= 400 & missing(group_id)
replace group_id = 8 if id <= 500 & missing(group_id)
gen temp_subgroup_id = .
replace temp_subgroup_id = floor((3)*runiform() + 2) if group_id < 6
replace temp_subgroup_id = floor((4)*runiform() + 2) if group_id < 8 & missing(temp_subgroup_id)
replace temp_subgroup_id = floor((5)*runiform() + 2) if missing(temp_subgroup_id)
egen subgroup_id = group(group_id temp_subgroup_id)
bysort subgroup_id : gen subgroup_size = _N
bysort group_id subgroup_id : gen tag = (_n == 1)
bysort group_id : egen outcomes_n = total(tag)
gen binary_x = floor(2*runiform())
//================== locals: ==================
local covariates binary_x
local times = 8
// times is equal to the number of group_ids
//================== loop in question: ==================
local counter = 1
forvalues i = 1/`times' {
preserve
keep if group_id==`i'
foreach covariate in `covariates' {
if `counter' == 1 {
mlogit subgroup_id `covariate'
sum outcomes_n, meanonly
local max = `r(max)'
local max_minus = `max' - 1
matrix mat_`covariate' = J(`max_minus',1,0)
forvalues j = 1/`max_minus' {
mat V = e(V)
mat b = e(b)
local z = b[1+2*(`j'-1),1] / ( V[1+2*(`j'-1),1+2*(`j'-1)] ) ^ (.5)
matrix mat_`covariate'[`j',1] = `z'
}
}
else {
mlogit subgroup_id `covariate'
sum outcomes_n, meanonly
local max `r(max)'
local max_minus = `max' - 1
matrix mat_`covariate'_temp = J(`max_minus',1,0)
forvalues j = 1/`max_minus' {
mat V = e(V)
mat b = e(b)
local z = b[1+2*(`j'-1),1] / ( V[1+2*(`j'-1),1+2*(`j'-1)] ) ^ (.5)
matrix mat_`covariate'_temp[`j',1] = `z'
matrix mat_`covariate' = mat_`covariate' \ mat_`covariate'_temp
}
matrix mat_`covariate' = mat_`covariate' \ mat_`covariate'_temp
}
}
local counter = `counter' + 1
restore
}
//================== symptoms: ==================
matrix list mat_binary_x
我试图弄清楚我的代码中有什么问题,但一直无法找到问题所在(尽管我发现了一些其他较小的错误,但 none 对主要问题 - 如果有多个错误,我不会感到惊讶)。
考虑当 i == 1
和 max_minus == 2
时最简单的情况:
preserve
keep if group_id == 1
summarize outcomes_n, meanonly
local max = `r(max)'
local max_minus = `max' - 1
mlogit subgroup_id binary_x
matrix V = e(V)
matrix b = e(b)
这会产生以下结果:
. matrix list V
symmetric V[6,6]
1: 1: 2: 2: 3: 3:
o. o.
binary_x _cons binary_x _cons binary_x _cons
1:binary_x .46111111
1:_cons -.225 .225
2:o.binary_x 0 0 0
2:o._cons 0 0 0 0
3:binary_x .2111111 -.09999999 0 0 .47896825
3:_cons -.09999999 .09999999 0 0 -.24285714 .24285714
. matrix list b
b[1,6]
1: 1: 2: 2: 3: 3:
o. o.
binary_x _cons binary_x _cons binary_x _cons
y1 .10536052 -.22314364 0 0 .23889194 -.35667502
. local j = `max_minus'
. display "z = `= b[1+2*(`j'-1),1] / ( V[1+2*(`j'-1),1+2*(`j'-1)] ) ^ (.5)'"
z = .
缺少 z
的值,因为您正在除以
不存在的矩阵 e(b)
。换句话说,你的循环是
设置不正确并替换了不正确的值。
我希望 运行 一系列多项式 logits(每个感兴趣的协变量 600ish)并从每个中收集 z 统计量(我不关心这些记录的顺序)。
这些 mlogits 运行 在我的一小部分数据上(共享一个组 ID)。 mlogit 涉及不同数量的结果 (n),并且将从每个 mlogit 收集 (n - 1) z 个统计数据。每个 mlogit 都采用以下形式: y = a + _b*x + \epsilon 其中 y 可以取 2 到 9 个值(在我的数据中),尽管平均值是 3.7.
我认为困难在于将这些 z-stats 从 mlogit 中提取出来,因为我不知道如何直接调用 z-stats 矩阵。我的解决方案是从 e(V) 和 e(b) 矩阵构造 z-stats。对于 mlogit 的每次迭代,我构建了一个 z-stats 矩阵;然后我将其附加到之前的 z-stats 矩阵(从而构建所有计算的矩阵)。不幸的是,我的代码似乎没有正确执行此操作。
症状如下。矩阵 mat_covariate 包含许多缺失值(在我所做的故障排除中,超过一半的矩阵值缺失)。它还包括许多零(这是可能的,但不太可能——尤其是在这个比率下,大约 16%)。如所写,代码尚未抑制 mlogits I 运行,因此我可以返回并检查是什么使其进入矩阵。每个 mlogit 最多记录一个值,但这些值通常会记录多次。 40% 的 mlogits 没有任何记录。
相关循环如下:
local counter = 1
forvalues i = 1/`times' {
preserve
keep if group_id==`i'
foreach covariate in `covariates' {
if `counter' == 1 {
mlogit class `covariate'
sum outcomes_n, meanonly
local max = `r(max)'
local max_minus = `max' - 1
matrix mat_`covariate' = J(`max_minus',1,0)
forvalues j = 1/`max_minus' {
mat V = e(V)
mat b = e(b)
local z = b[1+2*(`j'-1),1] / ( V[1+2*(`j'-1),1+2*(`j'-1)] ) ^ (.5)
matrix mat_`covariate'[`j',1] = `z'
}
}
else {
mlogit class `covariate'
sum outcomes_n, meanonly
local max `r(max)'
local max_minus = `max' - 1
matrix mat_`covariate'_temp = J(`max_minus',1,0)
forvalues j = 1/`max_minus' {
mat V = e(V)
mat b = e(b)
local z = b[1+2*(`j'-1),1] / ( V[1+2*(`j'-1),1+2*(`j'-1)] ) ^ (.5)
matrix mat_`covariate'_temp[`j',1] = `z'
matrix mat_`covariate' = mat_`covariate' \ mat_`covariate'_temp
}
matrix mat_`covariate' = mat_`covariate' \ mat_`covariate'_temp
}
}
local counter = `counter'+1
restore
}
为什么我在循环中做了一些事情的一些原因。我相信这些东西有效,但它们不是我的第一直觉,我不清楚为什么我的第一直觉不起作用。如果有一个 simpler/more 优雅的方法来解决它们,那将是一个很好的奖励:
- 主要if/else(和计数器)是为了解决我无法在尚未定义矩阵时将其定义为自身函数的问题。
- 我为 max 定义了一个局部变量,为 (max-1) 定义了一个单独的变量。 forvalues 循环不接受 "1/(`max'-1) {" 我不确定为什么。
我创建了一些可用于重现此问题的示例数据。下面是一个 .do 文件的代码,它设置数据、循环的局部变量、上面的循环,并通过显示有问题的矩阵来演示症状:
clear all
version 14
//================== sample data: ==================
set obs 500
set seed 12345
gen id = _n
gen group_id = .
replace group_id = 1 if id <= 50
replace group_id = 2 if id <= 100 & missing(group_id)
replace group_id = 3 if id <= 150 & missing(group_id)
replace group_id = 4 if id <= 200 & missing(group_id)
replace group_id = 5 if id <= 250 & missing(group_id)
replace group_id = 6 if id <= 325 & missing(group_id)
replace group_id = 7 if id <= 400 & missing(group_id)
replace group_id = 8 if id <= 500 & missing(group_id)
gen temp_subgroup_id = .
replace temp_subgroup_id = floor((3)*runiform() + 2) if group_id < 6
replace temp_subgroup_id = floor((4)*runiform() + 2) if group_id < 8 & missing(temp_subgroup_id)
replace temp_subgroup_id = floor((5)*runiform() + 2) if missing(temp_subgroup_id)
egen subgroup_id = group(group_id temp_subgroup_id)
bysort subgroup_id : gen subgroup_size = _N
bysort group_id subgroup_id : gen tag = (_n == 1)
bysort group_id : egen outcomes_n = total(tag)
gen binary_x = floor(2*runiform())
//================== locals: ==================
local covariates binary_x
local times = 8
// times is equal to the number of group_ids
//================== loop in question: ==================
local counter = 1
forvalues i = 1/`times' {
preserve
keep if group_id==`i'
foreach covariate in `covariates' {
if `counter' == 1 {
mlogit subgroup_id `covariate'
sum outcomes_n, meanonly
local max = `r(max)'
local max_minus = `max' - 1
matrix mat_`covariate' = J(`max_minus',1,0)
forvalues j = 1/`max_minus' {
mat V = e(V)
mat b = e(b)
local z = b[1+2*(`j'-1),1] / ( V[1+2*(`j'-1),1+2*(`j'-1)] ) ^ (.5)
matrix mat_`covariate'[`j',1] = `z'
}
}
else {
mlogit subgroup_id `covariate'
sum outcomes_n, meanonly
local max `r(max)'
local max_minus = `max' - 1
matrix mat_`covariate'_temp = J(`max_minus',1,0)
forvalues j = 1/`max_minus' {
mat V = e(V)
mat b = e(b)
local z = b[1+2*(`j'-1),1] / ( V[1+2*(`j'-1),1+2*(`j'-1)] ) ^ (.5)
matrix mat_`covariate'_temp[`j',1] = `z'
matrix mat_`covariate' = mat_`covariate' \ mat_`covariate'_temp
}
matrix mat_`covariate' = mat_`covariate' \ mat_`covariate'_temp
}
}
local counter = `counter' + 1
restore
}
//================== symptoms: ==================
matrix list mat_binary_x
我试图弄清楚我的代码中有什么问题,但一直无法找到问题所在(尽管我发现了一些其他较小的错误,但 none 对主要问题 - 如果有多个错误,我不会感到惊讶)。
考虑当 i == 1
和 max_minus == 2
时最简单的情况:
preserve
keep if group_id == 1
summarize outcomes_n, meanonly
local max = `r(max)'
local max_minus = `max' - 1
mlogit subgroup_id binary_x
matrix V = e(V)
matrix b = e(b)
这会产生以下结果:
. matrix list V
symmetric V[6,6]
1: 1: 2: 2: 3: 3:
o. o.
binary_x _cons binary_x _cons binary_x _cons
1:binary_x .46111111
1:_cons -.225 .225
2:o.binary_x 0 0 0
2:o._cons 0 0 0 0
3:binary_x .2111111 -.09999999 0 0 .47896825
3:_cons -.09999999 .09999999 0 0 -.24285714 .24285714
. matrix list b
b[1,6]
1: 1: 2: 2: 3: 3:
o. o.
binary_x _cons binary_x _cons binary_x _cons
y1 .10536052 -.22314364 0 0 .23889194 -.35667502
. local j = `max_minus'
. display "z = `= b[1+2*(`j'-1),1] / ( V[1+2*(`j'-1),1+2*(`j'-1)] ) ^ (.5)'"
z = .
缺少 z
的值,因为您正在除以
不存在的矩阵 e(b)
。换句话说,你的循环是
设置不正确并替换了不正确的值。