Skip to content

Commit 4887c70

Browse files
StatsBase -> StatsAPI (#203)
* Update FixedEffectModel.jl StatsBase -> StatsAPI * Update Project.toml * Update FixedEffectModels.jl * Update fit.jl * Update Project.toml * Update Project.toml * Update Project.toml * Update FixedEffectModel.jl * Update FixedEffectModel.jl
1 parent 2662649 commit 4887c70

File tree

4 files changed

+40
-33
lines changed

4 files changed

+40
-33
lines changed

Project.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "FixedEffectModels"
22
uuid = "9d5cd8c9-2029-5cab-9928-427838db53e3"
3-
version = "1.6.7"
3+
version = "1.7.0"
44

55
[deps]
66
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
@@ -9,6 +9,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
99
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
1010
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
1111
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
12+
StatsAPI = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
1213
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
1314
StatsFuns = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
1415
StatsModels = "3eaba693-59b7-5ba5-a881-562e759f1c8d"
@@ -19,9 +20,10 @@ Vcov = "ec2bfdc2-55df-4fc9-b9ae-4958c2cf2486"
1920
DataFrames = "0.21, 0.22, 1.0"
2021
FixedEffects = "2"
2122
Reexport = "0.1, 0.2, 1.0"
23+
StatsAPI = "1"
2224
StatsBase = "0.33"
2325
StatsFuns = "0.9, 1"
2426
StatsModels = "0.6"
2527
Tables = "1"
26-
Vcov = "0.5"
28+
Vcov = "0.6"
2729
julia = "1.3"

src/FixedEffectModel.jl

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ struct FixedEffectModel <: RegressionModel
2424
contrasts::Dict
2525

2626
nobs::Int64 # Number of observations
27-
dof_residual::Int64 # nobs - degrees of freedoms
28-
df_FStat::Int64
27+
dof::Int64 # Number parameters estimated - has_intercept
28+
dof_residual::Int64 # nobs - degrees of freedoms
29+
dof_tstat::Int64 # dof used for t-test and F-stat
2930

3031
rss::Float64 # Sum of squared residuals
3132
tss::Float64 # Total sum of squares
@@ -49,30 +50,31 @@ has_iv(m::FixedEffectModel) = m.F_kp !== nothing
4950
has_fe(m::FixedEffectModel) = has_fe(m.formula)
5051

5152

52-
# Check API at https://github.com/JuliaStats/StatsBase.jl/blob/11a44398bdc16a00060bc6c2fb65522e4547f159/src/statmodels.jl
53-
# fields
54-
StatsBase.coef(m::FixedEffectModel) = m.coef
55-
StatsBase.coefnames(m::FixedEffectModel) = m.coefnames
56-
StatsBase.responsename(m::FixedEffectModel) = m.yname
57-
StatsBase.vcov(m::FixedEffectModel) = m.vcov
58-
StatsBase.nobs(m::FixedEffectModel) = m.nobs
59-
StatsBase.dof_residual(m::FixedEffectModel) = m.dof_residual
60-
StatsBase.r2(m::FixedEffectModel) = m.r2
61-
StatsBase.adjr2(m::FixedEffectModel) = m.adjr2
62-
StatsBase.islinear(m::FixedEffectModel) = true
63-
StatsBase.deviance(m::FixedEffectModel) = m.tss
64-
StatsBase.rss(m::FixedEffectModel) = m.rss
65-
StatsBase.mss(m::FixedEffectModel) = deviance(m) - rss(m)
66-
67-
68-
function StatsBase.confint(m::FixedEffectModel; level::Real = 0.95)
69-
scale = tdistinvcdf(m.df_FStat, 1 - (1 - level) / 2)
53+
54+
StatsAPI.coef(m::FixedEffectModel) = m.coef
55+
StatsAPI.coefnames(m::FixedEffectModel) = m.coefnames
56+
StatsAPI.responsename(m::FixedEffectModel) = m.yname
57+
StatsAPI.vcov(m::FixedEffectModel) = m.vcov
58+
StatsAPI.nobs(m::FixedEffectModel) = m.nobs
59+
StatsAPI.dof(m::FixedEffectModel) = m.dof
60+
StatsAPI.dof_residual(m::FixedEffectModel) = m.dof_residual
61+
Vcov.dof_tstat(m::FixedEffectModel) = m.dof_tstat
62+
StatsAPI.r2(m::FixedEffectModel) = m.r2
63+
StatsAPI.adjr2(m::FixedEffectModel) = m.adjr2
64+
StatsAPI.islinear(m::FixedEffectModel) = true
65+
StatsAPI.deviance(m::FixedEffectModel) = m.tss
66+
StatsAPI.rss(m::FixedEffectModel) = m.rss
67+
StatsAPI.mss(m::FixedEffectModel) = deviance(m) - rss(m)
68+
69+
70+
function StatsAPI.confint(m::FixedEffectModel; level::Real = 0.95)
71+
scale = tdistinvcdf(Vcov.dof_tstat(m), 1 - (1 - level) / 2)
7072
se = stderror(m)
7173
hcat(m.coef - scale * se, m.coef + scale * se)
7274
end
7375

7476
# predict, residuals, modelresponse
75-
function StatsBase.predict(m::FixedEffectModel, t)
77+
function StatsAPI.predict(m::FixedEffectModel, t)
7678
# Require DataFrame input as we are using leftjoin and select from DataFrames here
7779
# Make sure fes are saved
7880
if has_fe(m)
@@ -95,7 +97,7 @@ function StatsBase.predict(m::FixedEffectModel, t)
9597
return out
9698
end
9799

98-
function StatsBase.residuals(m::FixedEffectModel, t)
100+
function StatsAPI.residuals(m::FixedEffectModel, t)
99101
if has_fe(m)
100102
m.residuals !== nothing || throw("To access residuals in a fixed effect regression, run `reg` with the option save = :residuals, and then access residuals with `residuals()`")
101103
residuals(m)
@@ -115,7 +117,7 @@ function StatsBase.residuals(m::FixedEffectModel, t)
115117
end
116118

117119

118-
function StatsBase.residuals(m::FixedEffectModel)
120+
function StatsAPI.residuals(m::FixedEffectModel)
119121
has_fe(m) || throw("To access residuals, use residuals(x, t) where t is a Table")
120122
m.residuals
121123
end
@@ -140,7 +142,7 @@ function fe(m::FixedEffectModel; keepkeys = false)
140142
end
141143

142144

143-
function StatsBase.coeftable(m::FixedEffectModel; level = 0.95)
145+
function StatsAPI.coeftable(m::FixedEffectModel; level = 0.95)
144146
cc = coef(m)
145147
se = stderror(m)
146148
coefnms = coefnames(m)
@@ -155,7 +157,7 @@ function StatsBase.coeftable(m::FixedEffectModel; level = 0.95)
155157
end
156158
tt = cc ./ se
157159
CoefTable(
158-
hcat(cc, se, tt, fdistccdf.(Ref(1), Ref(m.df_FStat), abs2.(tt)), conf_int[:, 1:2]),
160+
hcat(cc, se, tt, fdistccdf.(Ref(1), Ref(Vcov.dof_tstat(m)), abs2.(tt)), conf_int[:, 1:2]),
159161
["Estimate","Std.Error","t value", "Pr(>|t|)", "Lower 95%", "Upper 95%" ],
160162
["$(coefnms[i])" for i = 1:length(cc)], 4)
161163
end
@@ -186,7 +188,7 @@ format_scientific(x) = @sprintf("%.3f", x)
186188
function top(m::FixedEffectModel)
187189
out = [
188190
"Number of obs" sprint(show, nobs(m), context = :compact => true);
189-
"Degrees of freedom" sprint(show, nobs(m) - dof_residual(m), context = :compact => true);
191+
"Degrees of freedom" sprint(show, dof(m), context = :compact => true);
190192
"R2" format_scientific(r2(m));
191193
"R2 Adjusted" format_scientific(adjr2(m));
192194
"F-Stat" sprint(show, m.F, context = :compact => true);
@@ -225,7 +227,7 @@ function Base.show(io::IO, m::FixedEffectModel)
225227
coefnms = coefnms[newindex]
226228
end
227229
tt = cc ./ se
228-
mat = hcat(cc, se, tt, fdistccdf.(Ref(1), Ref(m.df_FStat), abs2.(tt)), conf_int[:, 1:2])
230+
mat = hcat(cc, se, tt, fdistccdf.(Ref(1), Ref(Vcov.dof_tstat(m)), abs2.(tt)), conf_int[:, 1:2])
229231
nr, nc = size(mat)
230232
colnms = ["Estimate","Std.Error","t value", "Pr(>|t|)", "Lower 95%", "Upper 95%"]
231233
rownms = ["$(coefnms[i])" for i = 1:length(cc)]

src/FixedEffectModels.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ using LinearAlgebra
1212
using Printf
1313
using Reexport
1414
using Statistics
15+
using StatsAPI
1516
using StatsBase
1617
using StatsFuns
1718
@reexport using StatsModels
@@ -37,4 +38,4 @@ has_iv,
3738
has_fe,
3839
Vcov
3940

40-
end
41+
end

src/fit.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,8 @@ function reg(
375375
end
376376
end
377377
dof_residual_ = max(1, nobs - size(X, 2) - dof_fes - dof_add)
378+
dof_ = max(1, size(X, 2) - (has_intercept | has_fe_intercept))
379+
378380

379381
nclusters = nothing
380382
if vcov isa Vcov.ClusterCovariance
@@ -388,8 +390,8 @@ function reg(
388390

389391
# Compute Fstat
390392
F = Fstat(coef, matrix_vcov, has_intercept)
391-
df_FStat_ = max(1, Vcov.df_FStat(vcov_data, vcov_method, has_intercept | has_fe_intercept))
392-
p = fdistccdf(max(length(coef) - (has_intercept | has_fe_intercept), 1), df_FStat_, F)
393+
dof_tstat_ = max(1, Vcov.dof_tstat(vcov_data, vcov_method, has_intercept | has_fe_intercept))
394+
p = fdistccdf(dof_, dof_tstat_, F)
393395
# Compute Fstat of First Stage
394396
if has_iv && first_stage
395397
Pip = Pi[(size(Pi, 1) - size(Z_res, 2) + 1):end, :]
@@ -449,5 +451,5 @@ function reg(
449451
esample = trues(N)
450452
end
451453

452-
return FixedEffectModel(coef, matrix_vcov, vcov, nclusters, esample, residuals2, augmentdf, fekeys, coef_names, response_name, formula_origin, formula_schema, contrasts, nobs, dof_residual_, df_FStat_, rss, tss_total, r2, adjr2, F, p, iterations, converged, r2_within, F_kp, p_kp)
454+
return FixedEffectModel(coef, matrix_vcov, vcov, nclusters, esample, residuals2, augmentdf, fekeys, coef_names, response_name, formula_origin, formula_schema, contrasts, nobs, dof_, dof_residual_, dof_tstat_, rss, tss_total, r2, adjr2, F, p, iterations, converged, r2_within, F_kp, p_kp)
453455
end

0 commit comments

Comments
 (0)