Skip to content

Commit faf49df

Browse files
committed
Match svyglm for ProbabilityWeights deviance, nulldeviance, and SE
1 parent 19e10d4 commit faf49df

4 files changed

Lines changed: 11 additions & 8 deletions

File tree

src/glmfit.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ end
8080
function deviance(r::GlmResp)
8181
wts = weights(r)
8282
d = sum(r.devresid)
83-
return wts isa ProbabilityWeights ? d * nobs(r) / sum(wts) : d
83+
return wts isa ProbabilityWeights ? d * length(r.y) / sum(wts) : d
8484
end
8585

8686
weights(r::GlmResp) = r.weights
@@ -323,7 +323,7 @@ function nulldeviance(m::GeneralizedLinearModel)
323323
end
324324
end
325325
if wts isa ProbabilityWeights
326-
dev /= sum(wts) / nobs(m)
326+
dev /= sum(wts) / length(y)
327327
end
328328
else
329329
X = fill(1.0, length(y), hasint ? 1 : 0)

src/linpred.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,10 @@ working_weights(x::LinPredModel) = working_weights(x.rr)
313313
function vcov(x::LinPredModel)
314314
if weights(x) isa ProbabilityWeights
315315
## n-1 degrees of freedom - This is coherent with the `R` package `survey`,
316-
## `STATA` uses n-k
317-
s = nobs(x) / (nobs(x) - 1)
316+
## `STATA` uses n-k. Use the full sample size (including zero-weighted obs)
317+
## so the correction matches `survey::svyglm`.
318+
n = length(response(x))
319+
s = n / (n - 1)
318320
mm = momentmatrix(x)
319321
A = invloglikhessian(x)
320322
if distr(x) isa Union{Gamma,InverseGaussian}

src/lm.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ function deviance(r::LmResp)
6666
v += abs2(y[i] - mu[i]) * weights[i]
6767
end
6868
end
69-
return weights isa ProbabilityWeights ? v ./ (sum(weights) / nobs(r)) : v
69+
return weights isa ProbabilityWeights ? v ./ (sum(weights) / length(r.y)) : v
7070
end
7171

7272
weights(r::LmResp) = r.weights
@@ -235,7 +235,7 @@ function nulldeviance(obj::LinearModel)
235235
v += abs2(y[i] - m) * weights[i]
236236
end
237237
end
238-
return v
238+
return weights isa ProbabilityWeights ? v / (sum(weights) / length(y)) : v
239239
end
240240

241241
function nullloglikelihood(m::LinearModel)

test/runtests.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,7 +2743,8 @@ end
27432743
glmod = glm(X, y, Normal(), weights=pweights(wts))
27442744
@test nobs(lmod) == nobs(glmod) == count(!iszero, wts)
27452745
@test dof_residual(lmod) == dof_residual(glmod) == count(!iszero, wts) - 2
2746-
@test deviance(lmod) deviance(glmod) 24.500813008130084
2746+
@test deviance(lmod) deviance(glmod) 30.626016260162601
2747+
@test nulldeviance(lmod) nulldeviance(glmod) 33.288888888888884
27472748
@test coef(lmod) coef(glmod) [3.6707317073170724, 0.20731707317073195]
2748-
@test stderror(lmod) stderror(glmod) [1.7617126628715203, 0.23455696986842048]
2749+
@test stderror(lmod) stderror(glmod) [1.7370721114074674, 0.2312762912372783]
27492750
end

0 commit comments

Comments
 (0)