Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ The objective of the package is similar to the Stata command [`reghdfe`](https:/
using DataFrames, RDatasets, FixedEffectModels
df = dataset("plm", "Cigar")
reg(df, @formula(Sales ~ NDI + fe(State) + fe(Year)), Vcov.cluster(:State), weights = :Pop)
# FixedEffectModel
# FixedEffectModel
# =========================================================================
# Number of obs: 1380 Converged: true
# Dependent variable: Sales Number of obs: 1,380
# dof (model): 1 dof (residuals): 45
# R²: 0.803 R² adjusted: 0.798
# F-statistic: 13.3382 P-value: 0.001
# R²: 0.803 R² adjusted: 0.791
# F-statistic: 13.3382 P-value: 0.0007
# R² within: 0.139 Iterations: 5
# =========================================================================
# Estimate Std. Error t-stat Pr(>|t|) Lower 95% Upper 95%
Expand Down
36 changes: 23 additions & 13 deletions src/FixedEffectModel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -299,26 +299,28 @@ end
##
##############################################################################

import StatsBase: NoQuote, PValue

function top(m::FixedEffectModel)
out = [
"Number of obs" sprint(show, nobs(m), context = :compact => true);
"Converged" m.converged;
"Dependent variable" string(responsename(m));
"Number of obs" replace(string(nobs(m)), r"(?<=\d)(?=(\d{3})+$)" => ",");
"dof (model)" sprint(show, dof(m), context = :compact => true);
"dof (residuals)" sprint(show, dof_residual(m), context = :compact => true);
"R²" @sprintf("%.3f",r2(m));
"R² adjusted" @sprintf("%.3f",adjr2(m));
"F-statistic" sprint(show, m.F, context = :compact => true);
"P-value" @sprintf("%.3f",m.p);
"P-value" sprint(show, PValue(m.p));
]
if has_iv(m)
out = vcat(out,
out = vcat(out,
[
"F-statistic (first stage)" sprint(show, m.F_kp, context = :compact => true);
"P-value (first stage)" @sprintf("%.3f",m.p_kp);
"P-value (first stage)" sprint(show, PValue(m.p_kp));
])
end
if has_fe(m)
out = vcat(out,
out = vcat(out,
[
"R² within" @sprintf("%.3f",m.r2_within);
"Iterations" sprint(show, m.iterations, context = :compact => true);
Expand All @@ -328,8 +330,6 @@ function top(m::FixedEffectModel)
end



import StatsBase: NoQuote, PValue
function Base.show(io::IO, m::FixedEffectModel)
ct = coeftable(m)
#copied from show(iio,cf::Coeftable)
Expand All @@ -353,22 +353,29 @@ function Base.show(io::IO, m::FixedEffectModel)
totwidth = sum(sum.(A)) + 2 * (length(A) - 1)


#intert my stuff which requires totwidth
ctitle = string(typeof(m))
halfwidth = div(totwidth - length(ctitle), 2)
print(io, " " ^ halfwidth * ctitle * " " ^ halfwidth)
#insert my stuff which requires totwidth
ctop = top(m)
for i in 1:size(ctop, 1)
ctop[i, 1] = ctop[i, 1] * ":"
end
# widen the table if a label/value pair does not fit in half of it:
# lpad would otherwise glue the value to its label and shift the row
needed = maximum(length(ctop[i, 1]) + 1 + length(string(ctop[i, 2])) for i in 1:size(ctop, 1))
totwidth = max(totwidth, 2 * needed + 2)
ctitle = string(typeof(m))
if has_iv(m)
ctitle *= " (IV)"
end
halfwidth = div(totwidth - length(ctitle), 2)
print(io, " " ^ halfwidth, ctitle)
println(io, '\n', repeat('=', totwidth))
halfwidth = div(totwidth, 2) - 1
interwidth = 2 + mod(totwidth, 2)
for i in 1:(div(size(ctop, 1) - 1, 2)+1)
print(io, ctop[2*i-1, 1])
print(io, lpad(ctop[2*i-1, 2], halfwidth - length(ctop[2*i-1, 1])))
print(io, " " ^interwidth)
if size(ctop, 1) >= 2*i
print(io, " " ^interwidth)
print(io, ctop[2*i, 1])
print(io, lpad(ctop[2*i, 2], halfwidth - length(ctop[2*i, 1])))
end
Expand All @@ -377,6 +384,9 @@ function Base.show(io::IO, m::FixedEffectModel)

# rest of coeftable code
println(io, repeat('=', totwidth))
if has_fe(m) && !m.converged
println(io, "Warning: demeaning did not converge; estimates may be unreliable")
end
print(io, repeat(' ', sum(A[1])))
for j in 1:length(colnms)
print(io, " ", lpad(colnms[j], sum(A[j+1])))
Expand Down
Loading