diff --git a/Project.toml b/Project.toml index b48a9be..9ede411 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "InteractiveFixedEffectModels" uuid = "80307280-efb2-5c5d-af8b-a9c15821677b" -version = "1.3.0" +version = "1.3.1" [deps] DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" @@ -23,7 +23,7 @@ Vcov = "ec2bfdc2-55df-4fc9-b9ae-4958c2cf2486" [compat] DataFrames = "0.21, 0.22, 1" FillArrays = "0.7, 0.8, 0.9, 0.10, 0.11, 0.12, 0.13, 1" -FixedEffectModels = "1.11" +FixedEffectModels = "1.12" FixedEffects = "2" GroupedArrays = "0.3" LeastSquaresOptim = "0.7, 0.8" diff --git a/README.md b/README.md index 6e3251e..94cb212 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build status](https://github.com/matthieugomez/InteractiveFixedEffectModels.jl/workflows/CI/badge.svg)](https://github.com/matthieugomez/InteractiveFixedEffectModels.jl/actions) +[![Build status](https://github.com/FixedEffects/InteractiveFixedEffectModels.jl/workflows/CI/badge.svg)](https://github.com/FixedEffects/InteractiveFixedEffectModels.jl/actions) [![Coverage Status](https://coveralls.io/repos/matthieugomez/InteractiveFixedEffectModels.jl/badge.svg?branch=master&service=github)](https://coveralls.io/github/matthieugomez/InteractiveFixedEffectModels.jl?branch=master) ## Installation diff --git a/src/fit.jl b/src/fit.jl index a504ad2..9447984 100644 --- a/src/fit.jl +++ b/src/fit.jl @@ -67,21 +67,29 @@ function regife( Symbol(fesymbol(a)) ∉ factor_vars && error("FixedEffect should correspond to id or time dimension of the factor model") end end - fes, ids, fekeys, formula = FixedEffectModels.parse_fixedeffect(df, formula) - has_fes = !isempty(fes) - has_fes_intercept = false - ## Compute factors, an array of AbtractFixedEffects + formula, formula_fes = FixedEffectModels.parse_fe(formula) + has_fes = formula_fes != FormulaTerm(ConstantTerm(0), ConstantTerm(0)) + + fes, feids, fekeys = FixedEffectModels.parse_fixedeffect(df, formula_fes) + has_fe_intercept = any(fe.interaction isa UnitWeights for fe in fes) + + # remove intercept if absorbed by fixed effects + if has_fe_intercept + formula = FormulaTerm(formula.lhs, tuple(InterceptTerm{false}(), (term for term in eachterm(formula.rhs) if !isa(term, Union{ConstantTerm,InterceptTerm}))...)) + end + has_intercept = hasintercept(formula) + + if has_fes - if any([isa(fe.interaction, Ones) for fe in fes]) - formula = FormulaTerm(formula.lhs, tuple(ConstantTerm(0), (t for t in eachterm(formula.rhs) if t!= ConstantTerm(1))...)) - has_fes_intercept = true + if any(fe.interaction isa UnitWeights for fe in fes) + has_fe_intercept = true end fes = FixedEffect[fe[esample] for fe in fes] feM = AbstractFixedEffectSolver{Float64}(fes, weights, Val{:cpu}) end - has_intercept = ConstantTerm(1) ∈ eachterm(formula.rhs) + iterations = 0 @@ -101,7 +109,7 @@ function regife( formula_schema = apply_schema(formula, schema(formula, subdf, contrasts), StatisticalModel) y = convert(Vector{Float64}, response(formula_schema, subdf)) - tss_total = tss(y, has_intercept || has_fes_intercept, weights) + tss_total = tss(y, has_intercept | has_fe_intercept, weights) X = convert(Matrix{Float64}, modelmatrix(formula_schema, subdf)) @@ -227,7 +235,7 @@ function regife( # compute various r2 nobs = sum(esample) rss = sum(abs2, residualsm) - _tss = tss(ym ./ sqrtw, has_intercept || has_fes_intercept, weights) + _tss = tss(ym ./ sqrtw, has_intercept | has_fe_intercept, weights) r2_within = 1 - rss / _tss rss = sum(abs2, residuals) @@ -269,8 +277,8 @@ function regife( # get fixed effect newfes, b, c = solve_coefficients!(oldresiduals, feM; tol = tol, maxiter = maxiter) for j in 1:length(fes) - augmentdf[!, ids[j]] = Vector{Union{Float64, Missing}}(missing, length(esample)) - augmentdf[esample, ids[j]] = newfes[j] + augmentdf[!, feids[j]] = Vector{Union{Float64, Missing}}(missing, length(esample)) + augmentdf[esample, feids[j]] = newfes[j] end end end