marcpabst / anova.jl Goto Github PK
View Code? Open in Web Editor NEWProvides a Simple Way to Calculate ANOVAs From Fitted Linear Models.
License: Other
Provides a Simple Way to Calculate ANOVAs From Fitted Linear Models.
License: Other
I tried to add ANOVA, but got this error:
ERROR: Unsatisfiable requirements detected for package ANOVA [0825541b]:
ANOVA [0825541b] log: ├─possible versions are: [0.0.1, 0.1.0] or uninstalled ├─restricted to versions * by an explicit requirement, leaving only versions [0.0.1, 0.1.0] ├─restricted by julia compatibility requirements to versions: 0.1.0 or uninstalled, leaving only versions: 0.1.0 └─restricted by compatibility requirements with StatsModels [3eaba693] to versions: 0.0.1 or uninstalled — no versions left
└─StatsModels [3eaba693] log: ├─possible versions are: [0.0.1-0.0.2, 0.1.0, 0.2.0-0.2.6, 0.3.0-0.3.1, 0.4.0, 0.5.0, 0.6.0-0.6.3] or uninstalled ├─restricted by compatibility requirements with DataFrames [a93c6f00] to versions: [0.1.0, 0.2.0-0.2.6, 0.3.0-0.3.1, 0.4.0, 0.5.0, 0.6.0-0.6.3] or uninstalled
│ └─DataFrames [a93c6f00] log: │ ├─possible versions are: [0.1.0, 0.2.0-0.2.5, 0.3.0-0.3.16, 0.4.0-0.4.3, 0.5.0-0.5.12, 0.6.0-0.6.11, 0.7.0-0.7.8, 0.8.0-0.8.5, 0.9.0-0.9.1, 0.10.0-0.10.1, 0.11.0-0.11.7, 0.12.0, 0.13.0-0.13.1, 0.14.0-0.14.1, 0.15.0-0.15.2, 0.16.0, 0.17.0-0.17.1, 0.18.0-0.18.4, 0.19.0-0.19.3] or uninstalled
│ ├─restricted to versions * by NeuroAnalysis [088af2c0], leaving only versions [0.1.0, 0.2.0-0.2.5, 0.3.0-0.3.16, 0.4.0-0.4.3, 0.5.0-0.5.12, 0.6.0-0.6.11, 0.7.0-0.7.8, 0.8.0-0.8.5, 0.9.0-0.9.1, 0.10.0-0.10.1, 0.11.0-0.11.7, 0.12.0, 0.13.0-0.13.1, 0.14.0-0.14.1, 0.15.0-0.15.2, 0.16.0, 0.17.0-0.17.1, 0.18.0-0.18.4, 0.19.0-0.19.3]
│ │ └─NeuroAnalysis [088af2c0] log: │ │ ├─possible versions are: 1.0.0 or uninstalled │ │ └─NeuroAnalysis [088af2c0] is fixed to version 1.0.0 │ └─restricted to versions 0.19.3 by an explicit requirement, leaving only versions 0.19.3 └─restricted by compatibility requirements with GLM [38e38edf] to versions: 0.6.0-0.6.3 └─GLM [38e38edf] log: ├─possible versions are: [0.2.0-0.2.5, 0.3.0-0.3.2, 0.4.0-0.4.8, 0.5.0-0.5.6, 0.6.0-0.6.1, 0.7.0, 0.8.0-0.8.1, 0.9.0, 0.10.0-0.10.1, 0.11.0, 1.0.0-1.0.2, 1.1.0-1.1.1, 1.2.0, 1.3.0-1.3.1] or uninstalled
├─restricted to versions * by NeuroAnalysis [088af2c0], leaving only versions [0.2.0-0.2.5, 0.3.0-0.3.2, 0.4.0-0.4.8, 0.5.0-0.5.6, 0.6.0-0.6.1, 0.7.0, 0.8.0-0.8.1, 0.9.0, 0.10.0-0.10.1, 0.11.0, 1.0.0-1.0.2, 1.1.0-1.1.1, 1.2.0, 1.3.0-1.3.1]
│ └─NeuroAnalysis [088af2c0] log: see above └─restricted to versions 1.3.1 by an explicit requirement, leaving only versions 1.3.1
is the v0.2 not updated on registry, or I have to clone it?
@PharmCat has implemented ANOVA type III for LinearMixedModels in https://github.com/PharmCat/ReplicateBE.jl. Would it possible to have the functionality ported to this package?
I tried to install this and got all sorts of dependency issues
julia> using ANOVA
│ Package ANOVA not found, but a package named ANOVA is available from a registry.
│ Install package?
│ (@v1.7) pkg> add ANOVA
└ (y/n) [y]:
Resolving package versions...
ERROR: Unsatisfiable requirements detected for package StatsBase [2913bbd2]:
StatsBase [2913bbd2] log:
├─possible versions are: 0.24.0-0.33.16 or uninstalled
├─restricted to versions 0.30-0.33 by DiscriminantAnalysis [2091bfbe], leaving only versions 0.30.0-0.33.16
│ └─DiscriminantAnalysis [2091bfbe] log:
│ ├─possible versions are: 0.1.0 or uninstalled
│ └─DiscriminantAnalysis [2091bfbe] is fixed to version 0.1.0
├─restricted by compatibility requirements with Lasso [b4fcebef] to versions: 0.24.0-0.32.2, leaving only versions: 0.30.0-0.32.2
│ └─Lasso [b4fcebef] log:
│ ├─possible versions are: 0.1.1-0.6.3 or uninstalled
│ ├─restricted to versions * by an explicit requirement, leaving only versions 0.1.1-0.6.3
│ └─restricted by compatibility requirements with Distributions [31c24e10] to versions: 0.1.1-0.5.2 or uninstalled, leaving only versions: 0.1.1-0.5.2
│ └─Distributions [31c24e10] log:
│ ├─possible versions are: 0.16.0-0.25.49 or uninstalled
│ ├─restricted to versions * by an explicit requirement, leaving only versions 0.16.0-0.25.49
│ ├─restricted by compatibility requirements with ANOVA [0825541b] to versions: 0.16.0-0.23.12
│ │ └─ANOVA [0825541b] log:
│ │ ├─possible versions are: 0.1.0 or uninstalled
│ │ └─restricted to versions * by an explicit requirement, leaving only versions 0.1.0
│ └─restricted by compatibility requirements with Lasso [b4fcebef] to versions: [0.16.0-0.21.12, 0.23.0-0.23.12]
│ └─Lasso [b4fcebef] log: see above
└─restricted by compatibility requirements with EvalMetrics [251d5f9e] to versions: 0.33.0-0.33.16 — no versions left
└─EvalMetrics [251d5f9e] log:
├─possible versions are: 0.1.0-0.2.1 or uninstalled
└─restricted to versions * by an explicit requirement, leaving only versions 0.1.0-0.2.1
Stacktrace:
[1] propagate_constraints!(graph::Pkg.Resolve.Graph, sources::Set{Int64}; log_events::Bool)
@ Pkg.Resolve /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/Resolve/graphtype.jl:1063
[2] propagate_constraints! (repeats 2 times)
@ /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/Resolve/graphtype.jl:1000 [inlined]
[3] simplify_graph!(graph::Pkg.Resolve.Graph, sources::Set{Int64}; clean_graph::Bool)
@ Pkg.Resolve /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/Resolve/graphtype.jl:1519
[4] simplify_graph! (repeats 2 times)
@ /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/Resolve/graphtype.jl:1519 [inlined]
[5] resolve_versions!(env::Pkg.Types.EnvCache, registries::Vector{Pkg.Registry.RegistryInstance}, pkgs::Vector{Pkg.Types.PackageSpec}, julia_version::VersionNumber)
@ Pkg.Operations /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/Operations.jl:335
[6] targeted_resolve(env::Pkg.Types.EnvCache, registries::Vector{Pkg.Registry.RegistryInstance}, pkgs::Vector{Pkg.Types.PackageSpec}, preserve::Pkg.Types.PreserveLevel, julia_version::VersionNumber)
@ Pkg.Operations /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/Operations.jl:1154
[7] tiered_resolve(env::Pkg.Types.EnvCache, registries::Vector{Pkg.Registry.RegistryInstance}, pkgs::Vector{Pkg.Types.PackageSpec}, julia_version::VersionNumber)
@ Pkg.Operations /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/Operations.jl:1139
[8] _resolve(io::Base.TTY, env::Pkg.Types.EnvCache, registries::Vector{Pkg.Registry.RegistryInstance}, pkgs::Vector{Pkg.Types.PackageSpec}, preserve::Pkg.Types.PreserveLevel, julia_version::VersionNumber)
@ Pkg.Operations /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/Operations.jl:1160
[9] add(ctx::Pkg.Types.Context, pkgs::Vector{Pkg.Types.PackageSpec}, new_git::Set{Base.UUID}; preserve::Pkg.Types.PreserveLevel, platform::Base.BinaryPlatforms.Platform)
@ Pkg.Operations /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/Operations.jl:1176
[10] add(ctx::Pkg.Types.Context, pkgs::Vector{Pkg.Types.PackageSpec}; preserve::Pkg.Types.PreserveLevel, platform::Base.BinaryPlatforms.Platform, kwargs::Base.Pairs{Symbol, Base.TTY, Tuple{Symbol}, NamedTuple{(:io,), Tuple{Base.TTY}}})
@ Pkg.API /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/API.jl:268
[11] add(pkgs::Vector{Pkg.Types.PackageSpec}; io::Base.TTY, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ Pkg.API /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/API.jl:149
[12] add(pkgs::Vector{Pkg.Types.PackageSpec})
@ Pkg.API /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/API.jl:144
[13] #add#27
@ /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/API.jl:142 [inlined]
[14] add
@ /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/API.jl:142 [inlined]
[15] try_prompt_pkg_add(pkgs::Vector{Symbol})
@ Pkg.REPLMode /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/Pkg/src/REPLMode/REPLMode.jl:710
[16] #invokelatest#2
@ ./essentials.jl:716 [inlined]
[17] invokelatest
@ ./essentials.jl:714 [inlined]
[18] check_for_missing_packages_and_run_hooks(ast::Any)
@ REPL /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/REPL.jl:175
[19] eval_user_input(ast::Any, backend::REPL.REPLBackend)
@ REPL /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/REPL.jl:145
[20] repl_backend_loop(backend::REPL.REPLBackend)
@ REPL /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/REPL.jl:244
[21] start_repl_backend(backend::REPL.REPLBackend, consumer::Any)
@ REPL /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/REPL.jl:229
[22] run_repl(repl::REPL.AbstractREPL, consumer::Any; backend_on_current_task::Bool)
@ REPL /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/REPL.jl:362
[23] run_repl(repl::REPL.AbstractREPL, consumer::Any)
@ REPL /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/REPL/src/REPL.jl:349
[24] (::Base.var"#930#932"{Bool, Bool, Bool})(REPL::Module)
@ Base ./client.jl:394
[25] #invokelatest#2
@ ./essentials.jl:716 [inlined]
[26] invokelatest
@ ./essentials.jl:714 [inlined]
[27] run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_file::Bool, color_set::Bool)
@ Base ./client.jl:379
[28] exec_options(opts::Base.JLOptions)
@ Base ./client.jl:309
[29] _start()
@ Base ./client.jl:495
I know this isn't being actively developed, but it would be handy if it could be kept up-to-date
as far as loading.
Thanks
I still do not understand how to use GLM to do ANOVA. Nor do I understand what EffectsCoding()
is, or what contrasts
do in a call to fit
.
So below is something I made - a simple interface to take a number of vectors as inputs, and preform anova on them, without making a GLM. My proposition is to include this interface in the package, for users like myself:
using PrettyTables, Statistics, Distributions
SS(inputs::AbstractArray) = sum((i - mean(inputs))^2 for i in inputs)
SSW(all_obs::AbstractVector...) = sum(SS.(all_obs))
SSB(all_obs::AbstractVector...) = sum(length(ys) * (mean(ys) - mean(vcat(all_obs...)))^2 for ys in all_obs)
function SST(all_obs::AbstractVector...)
ys = vcat(all_obs...)
sum((y - mean(ys))^2 for y in ys)
end
function anova1(all_obs_input::AbstractVector...)
all_obs = all_obs_input .|> skipmissing .|> collect
observations = vcat(all_obs...)
SS = [SSB(all_obs...), SSW(all_obs...), SST(all_obs...)]
df = [length(all_obs) - 1, length(observations) - length(all_obs), length(observations) - 1]
S² = [SS[i] / df[i] for i = 1:3]
TS = round(S²[1] / S²[2], digits = 5)
dist = FDist(df[1], df[2])
p_val = round(1 - cdf(dist, TS[1]), digits = 5)
table = pretty_table(hcat([:Between, :Within, :Total], SS, df, S²),
header = ["Variation", "SS", "df", "S²"],
alignment = :c)
println("Test statistic = $(TS)")
println("p-value = $(p_val)")
return table
end
v1 = [missing, 4, 2, 4]
v2 = [-1, 0, missing, 1]
v3 = [-2, 1, 1, missing]
anova1(v1, v2, v3)
#returns
┌───────────┬─────────┬────┬─────────┐
│ Variation │ SS │ df │ S² │
├───────────┼─────────┼────┼─────────┤
│ Between │ 22.2222 │ 2 │ 11.1111 │
│ Within │ 10.6667 │ 6 │ 1.77778 │
│ Total │ 32.8889 │ 8 │ 4.11111 │
└───────────┴─────────┴────┴─────────┘
Test statistic = 6.25
p-value = 0.03411
The following can be added to allow matrix inputs, similar to the API i encountered in MATLAB.
anova1(all_obs_input::AbstractMatrix) = anova1(Vector.(eachcol(all_obs_input))...)
anova1([v1 v2 v3])
If this is to be THE package for ANOVA in Julia, I think that an API without using GLM should be part of it, because
a) it is simpler to use, and does not require understanding of GLM
b) One can use GLM directly, should one already be fluent in its use, to do ANOVA. This package should have a low bar of entry - it is currently too high for me.
Perhaps a bit more references in the readme could help new users, some suggestions are here. I'm not sure what are types I, II, III of ANOVA? What is the source of this terminology?
I know nothing about linear models, so the requirement to define a linear model is not clear. Could you please provide examples of how to specify models that will be recognized (factor, interaction term, etc.)? And in the case of a type 3 (which I see is cased in the code but the README says is forthcoming), how do you specify which factors are random or fixed?
I encourage the implementation to be based solely on the StatsBase.StatisticalModel
/ StatsBase.RegressionModel
API such that it works with any regression model rather than limiting it to only the GLM struct. As for the GLM, I believe it wasn't robust to allowrankdeficient
which could benefit from the generalization and checks. If you need methods beyond the current API, do reach out and we can expand the API to accommodate it.
Would it be possible to add compatibility with the recently update DataFrames package?
When requesting to install DataFrames
version 1 (which I need for other packages), I get:
julia> Pkg.add(Pkg.PackageSpec(;name="DataFrames", version="1.0"))
Resolving package versions...
ERROR: Unsatisfiable requirements detected for package DataFrames [a93c6f00]:
DataFrames [a93c6f00] log:
├─possible versions are: 0.11.7-1.2.2 or uninstalled
├─restricted to versions * by KmerTools [1bdae644], leaving only versions 0.11.7-1.2.2
│ └─KmerTools [1bdae644] log:
│ ├─possible versions are: 0.1.0 or uninstalled
│ └─KmerTools [1bdae644] is fixed to version 0.1.0
├─restricted to versions 1.0 by an explicit requirement, leaving only versions 1.0.0-1.0.2
└─restricted by compatibility requirements with ANOVA [0825541b] to versions: 0.11.7-0.21.8 — no versions left
└─ANOVA [0825541b] log:
├─possible versions are: 0.1.0 or uninstalled
└─restricted to versions * by an explicit requirement, leaving only versions 0.1.0
README.md
states that "more convenient way to create ANOVAs (similar to the ez
package in R) is planned." Are there still plans to do that? Is the package still maintained.
I am in need of the type III ANOVA à la SAS for GLM and MixedModels (with support for rank deficient). A similar tool is the car::Anova(::lmerMod, type = 3)
function in R. I am not an expert in ANOVA since I tend to use the standard Wald test routine, but for some software I am developing it is standard to report that ANOVA test. I am willing to implement these given some guidance on the procedure. I can start with a PR to handle the rank deficient LinearModel
. Given some guidance, I can also extend the functionality to the LinearMixedModel
.
I try to do classic bioequivalence testing for crossover design and get this error. Can anova could be done for this?
used code:
olscmax = lm(@formula(log(Cmax) ~ Sequence+Period+Formulation+Subject), df; dropcollinear = true)
Anova(olscmax)
Incompatible with ModelFrame v"0.6.3"
julia> Anova(model)
ERROR: type ModelFrame has no field terms
Stacktrace:
[1] getproperty(::Any, ::Symbol) at .\sysimg.jl:18
[2] (::getfield(ANOVA, Symbol("##Anova#1#4")))(::Int64, ::Type, ::StatsModels.TableRegressionModel{LinearModel{GLM.LmResp{Array{Float64,1}},GLM.DensePredChol{Float64,LinearAlgebra.Cholesky{Float64,Array{Float64,2}}}},Array{Float64,2}}) at C:\Users\xxx\.julia\dev\ANOVA\src\ANOVA.jl:26
[3] Anova(::StatsModels.TableRegressionModel{LinearModel{GLM.LmResp{Array{Float64,1}},GLM.DensePredChol{Float64,LinearAlgebra.Cholesky{Float64,Array{Float64,2}}}},Array{Float64,2}}) at C:\Users\xxx\.julia\dev\ANOVA\src\ANOVA.jl:20
[4] top-level scope at none:0
julia> Pkg.installed()["StatsModels"]
v"0.6.3"
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.