diff --git a/Project.toml b/Project.toml index 462f1ef..5d03f49 100644 --- a/Project.toml +++ b/Project.toml @@ -3,7 +3,7 @@ uuid = "a1dec852-9fe5-11e9-361f-8d9fde67cfa2" keywords = ["lenearmodel", "mixedmodel"] desc = "Mixed-effects models with flexible covariance structure." authors = ["Vladimir Arnautov "] -version = "0.16.2" +version = "0.16.3" [deps] DiffResults = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" diff --git a/docs/src/api.md b/docs/src/api.md index d48b79a..a453c5c 100644 --- a/docs/src/api.md +++ b/docs/src/api.md @@ -406,6 +406,13 @@ Metida.SpatialPowerD Metida.ScaledWeightedCov ``` +### Metida.ACOV + +```@docs +Metida.ACOV +``` + + ### Metida.dof_contain ```@docs diff --git a/docs/src/examples.md b/docs/src/examples.md index a10e836..be54c9f 100644 --- a/docs/src/examples.md +++ b/docs/src/examples.md @@ -1,10 +1,15 @@ -### Example 1 - Continuous and categorical predictors +## Example 1 - Continuous and categorical predictors ```@example lmmexample using Metida, CSV, DataFrames, CategoricalArrays, MixedModels; rds = CSV.File(joinpath(dirname(pathof(Metida)), "..", "test", "csv", "1fptime.csv"); types = [String, String, Float64, Float64]) |> DataFrame +rds2 = CSV.File(joinpath(dirname(pathof(Metida)), "..", "test", "csv", "ftdf3.csv"); types = [String, Float64, Float64, String, String, String, String, String, Float64]) |> DataFrame + + +devday = CSV.File(joinpath(dirname(pathof(Metida)), "..", "test", "csv", "devday.csv"); types = [Float64, String, String, String ]) |> DataFrame + nothing; # hide ``` @@ -27,7 +32,7 @@ mm = fit(MixedModel, fm, rds, REML=true) println(mm) #hide ``` -### Example 2 - Two random factors (Penicillin data) +## Example 2 - Two random factors (Penicillin data) Metida: @@ -51,7 +56,7 @@ mm = fit(MixedModel, fm2, df, REML=true) println(mm) #hide ``` -### Example 3 - Repeated ARMA/AR/ARH +## Example 3 - Repeated ARMA/AR/ARH ```@example lmmexample rds = CSV.File(joinpath(dirname(pathof(Metida)), "..", "test", "csv", "1freparma.csv"); types = [String, String, Float64, Float64]) |> DataFrame @@ -91,9 +96,9 @@ repeated = VarEffect(@covstr(1|subject&factor), ARH), fit!(lmm) ``` -### Example 4 - SAS relation +## Example 4 - SAS relation -#### Model 1 +### Model 1 ``` df0 = CSV.File(joinpath(dirname(pathof(Metida)), "..", "test", "csv", "df0.csv")) |> DataFrame @@ -116,7 +121,7 @@ REPEATED/GRP=formulation SUB=subject R; RUN; ``` -#### Model 2 +### Model 2 ``` lmm = LMM( @@ -138,7 +143,7 @@ REPEATED/GRP=formulation SUB=subject R; RUN; ``` -#### Model 3 +### Model 3 ``` lmm = LMM(@formula(var ~ sequence + period + formulation), df0; @@ -157,7 +162,7 @@ RANDOM subject/TYPE=VC G V; RUN; ``` -### Example 5 - Working with Effects.jl +## Example 5 - Working with Effects.jl ``` using Effects, StatsModels @@ -172,4 +177,73 @@ table_model = StatsModels.TableRegressionModel(lmm, lmm.mf, lmm.mm) emmeans(tm) effects(Dict(:period => ["1", "2", "3", "4"]), tm) +``` + + +## Unstructured covariance + +Unstructured covariance example. + + +Metida result: + +```@example lmmexample +lmm = Metida.LMM(@formula(response~factor), rds2; + random = Metida.VarEffect(Metida.@covstr(r1|subject), UN), + ) +Metida.fit!(lmm) +``` + +MixedModels result: + +```@example lmmexample +mm = fit(MixedModel, @formula(response ~ factor+ (0+r1|subject)), rds2, REML = true) +println(mm) #hide +``` + +## Aumented covariance (Experimental) + +Covariance modificator `ACOV()` can be used as second repeated effect. In this case covariance calculated with existed matrix, +that was build at previous step. For example addition `ACOV(AR)` to `DIAG` structure is the same as `ARH` if same blocking factor used. + +```@example lmmexample + lmm1 = Metida.LMM(@formula(response ~ 1), rds2; + repeated = [Metida.VarEffect(Metida.@covstr(r1|subject), Metida.DIAG), Metida.VarEffect(Metida.@covstr(1|subject), Metida.ACOV(Metida.AR))] + ) + Metida.fit!(lmm1) +``` + +```@example lmmexample + lmm2 = Metida.LMM(@formula(response ~ 1), rds2; + repeated = [Metida.VarEffect(Metida.@covstr(r1|subject), Metida.ARH)] + ) + Metida.fit!(lmm2) +``` + +R-part of variance-covariance matrix: + +```@example lmmexample +Metida.rmatrix(lmm1, 1) +``` + +If nested blocking factor used - covariance modification applyed only within that blocks: + +```@example lmmexample + lmm = Metida.LMM(@formula(response ~ 1), rds2; + repeated = [Metida.VarEffect(Metida.@covstr(r1|subject), Metida.DIAG), Metida.VarEffect(Metida.@covstr(1|subject), Metida.ACOV(Metida.AR))] + ) +Metida.fit!(lmm) +Metida.rmatrix(lmm, 1) +``` + +For nested models covariance structure can be expanded as follows: +* the first layer describes unstructured the device-device covariance; +* the second layer adds the time covariance for each device + +```@example lmmexample +lmm = Metida.LMM(@formula(resp ~ 0 + device), devday; + repeated = [Metida.VarEffect(Metida.@covstr(device|subj&day), Metida.UN), + Metida.VarEffect(Metida.@covstr(1|subj&device), Metida.ACOV(Metida.AR))] + ) + Metida.fit!(lmm) ``` \ No newline at end of file diff --git a/src/Metida.jl b/src/Metida.jl index c6438b6..740b2ad 100644 --- a/src/Metida.jl +++ b/src/Metida.jl @@ -36,6 +36,7 @@ SPPOW, SpatialPower, SPGAU, SpatialGaussian, RawCoding, UN, Unstructured, CovarianceType, +ACOV, fit, fit!, LMM, VarEffect, theta, logreml, m2logreml, m2logml, logml, thetalength, dof_satter, dof_contain, rankx, caic, lcontrast, typeiii, estimate, contrast, gmatrix, rmatrix, vmatrix!, responsename, nblocks, raneff, AbstractCovarianceType, AbstractCovmatMethod, MetidaModel, diff --git a/src/rmat.jl b/src/rmat.jl index 8c4a098..d4e4b7a 100644 --- a/src/rmat.jl +++ b/src/rmat.jl @@ -342,6 +342,76 @@ function rmat!(mx, θ, rz::AbstractMatrix, ::UN_, ::Int) mulαβαtinc!(mx, rz, rcov) return mx end + +# ACOV (AR) +function rmat!(mx::AbstractMatrix{T}, θ, ::AbstractMatrix, ct::ACOV_{AR_}, ::Int) where T + s = size(mx, 1) + ρ = θ[1] + if s > 1 + for n = 2:s + mxnn = mx[n, n] + @inbounds @simd for m = 1:n-1 + mxmm = mx[m, m] + mxmn = mx[m, n] + cov = sqrt(mxnn * mxmm) * ρ ^ (n - m) + if ct.a != 0 + if ct.a == 1 + mxmn = zero(T) + elseif ct.a == 2 + cov = zero(T) + elseif ct.a == 3 + @warn "covariance have existed value!" + elseif ct.a == 4 + @warn "covariance have existed value! replaced..." + mxmn = zero(T) + elseif ct.a == 5 + @warn "covariance have existed value! Save existed..." + cov = zero(T) + else + error("covariance have existed value!") + end + end + mx[m, n] = mxmn + cov + end + end + end + return mx +end + +# ACOV (CS) +function rmat!(mx::AbstractMatrix{T}, θ, ::AbstractMatrix, ct::ACOV_{CS_}, ::Int) where T + s = size(mx, 1) + ρ = θ[1] + if s > 1 + for n = 2:s + mxnn = mx[n, n] + @inbounds @simd for m = 1:n-1 + mxmm = mx[m, m] + mxmn = mx[m, n] + cov = sqrt(mxnn * mxmm) * ρ + if ct.a != 0 + if ct.a == 1 + mxmn = zero(T) + elseif ct.a == 2 + cov = zero(T) + elseif ct.a == 3 + @warn "covariance have existed value!" + elseif ct.a == 4 + @warn "covariance have existed value! replaced..." + mxmn = zero(T) + elseif ct.a == 5 + @warn "covariance have existed value! Save existed..." + cov = zero(T) + else + error("covariance have existed value!") + end + end + mx[m, n] = mxmn + cov + end + end + end + return mx +end ############################################################################### ############################################################################### ############################################################################### diff --git a/src/varstruct.jl b/src/varstruct.jl index 8dd78c7..e1d8f17 100644 --- a/src/varstruct.jl +++ b/src/varstruct.jl @@ -31,7 +31,7 @@ Macros for random/repeated effect model. # Example ```julia -@covstr(factor|subject) +@covstr(model|subject) ``` """ macro covstr(ex) @@ -64,7 +64,7 @@ Random/repeated effect. !!! note - Categorical factors are coded with `FullDummyCoding()` by default, use `coding` for other contrast codeing. + Categorical factors are coded with `FullDummyCoding()` by default, use `coding` for other contrast coding. # Example @@ -352,6 +352,9 @@ struct CovStructure{T, T2} <: AbstractCovarianceStructure subjblockdict = sabjcrossdicts(subjblockdict, dicts[i]) end end + if isa(repeated[1].covtype.s, ACOV_) + @warn "Using ACOV covariance additional effect at first position is meaningless." + end else subjblockdict = nothing end @@ -432,7 +435,15 @@ end # CONTRAST CODING ################################################################################ -function fill_coding_dict!(t::T, d::Dict, data) where T <: Union{ConstantTerm, InterceptTerm, FunctionTerm} +function fill_coding_dict!(t::T, d::Dict, data) where T <: Union{ConstantTerm, InterceptTerm} + return d +end +function fill_coding_dict!(t::T, d::Dict, data) where T <: FunctionTerm + if t.f === + + for i in t.args + fill_coding_dict!(i, d, data) + end + end return d end function fill_coding_dict!(t::T, d::Dict, data) where T <: Term diff --git a/src/vartypes.jl b/src/vartypes.jl index 2248d75..44fe8be 100644 --- a/src/vartypes.jl +++ b/src/vartypes.jl @@ -32,6 +32,11 @@ struct SPGAUD_ <: AbstractCovarianceType end struct UN_ <: AbstractCovarianceType end struct ZERO <: AbstractCovarianceType end +struct ACOV_{C <: AbstractCovarianceType} <: AbstractCovarianceType + c::C + a::Int +end + ################################################################################ # COVARIANCE TYPE ################################################################################ @@ -399,10 +404,37 @@ function Unstructured() end const UN = Unstructured() + +""" + ACOV(c, action = 0) + +!!! warning + Experimental + +Augmented (adjusted) covariance. Add additional correlations to existed R-part of variance covariance matrix. +Can be used with `AR` or `CS` types. + +`action` if existed covariance not equal sero: + +* 0 - add +* 1 - replace +* 2 - do nothing (use existed value) +* 3 - warning and add +* 4 - warning and replace +* 5 - warning and use existed value +* other - error + +""" +function ACOV(c; action = 0) + CovarianceType(ACOV_(c.s, action)) +end + function RZero() CovarianceType(ZERO(), false) end +####################################################################################### + function covstrparam(ct::SI_, ::Int)::Tuple{Int, Int} return (1, 0) end @@ -446,6 +478,10 @@ function covstrparam(ct::SPPOWD_, ::Int)::Tuple{Int, Int} return (2, 1) end +function covstrparam(ct::ACOV_{<:Union{CS_, AR_, SPPOW_}}, ::Int)::Tuple{Int, Int} + return (0, 1) +end + function covstrparam(ct::ZERO, ::Int)::Tuple{Int, Int} return (0, 0) end @@ -555,6 +591,10 @@ function rcoefnames(s, t, ct::UN_) return v end +function rcoefnames(s, t, ct::ACOV_{<: Union{CS_, AR_}}) + return ["ρ "] +end + function rcoefnames(s, t, ct::AbstractCovarianceType) v = Vector{String}(undef, t) v .= "Val " @@ -643,6 +683,9 @@ end function Base.show(io::IO, ct::UN_) print(io, "UN") end +function Base.show(io::IO, ct::ACOV_) + print(io, "ACOV(", ct.c, ")") +end function Base.show(io::IO, ct::ZERO) print(io, "No effect") end diff --git a/test/csv/devday.csv b/test/csv/devday.csv new file mode 100644 index 0000000..9b17f18 --- /dev/null +++ b/test/csv/devday.csv @@ -0,0 +1,201 @@ +resp,device,day,subj +8.72644141172539,A,d1,1 +5.042766927404885,A,d2,1 +4.186325590586714,B,d1,1 +1.5284483141734233,B,d2,1 +0.9795814766598748,C,d1,1 +-0.9859211795111515,C,d2,1 +1.815722019857775,D,d1,1 +0.6483360099159381,D,d2,1 +7.678877996324462,A,d1,2 +2.6894607393966203,A,d2,2 +1.604802444054944,B,d1,2 +0.06477952808780052,B,d2,2 +0.08761542039857528,C,d1,2 +-1.3153348196357393,C,d2,2 +-0.9458496052444734,D,d1,2 +-2.3047486276895612,D,d2,2 +5.450560693901975,A,d1,3 +9.686372619790028,A,d2,3 +1.718464421060092,B,d1,3 +0.030382263239601137,B,d2,3 +-2.4141035515735343,C,d1,3 +0.6145971257996419,C,d2,3 +-3.515779754752826,D,d1,3 +-0.7924377776322691,D,d2,3 +3.813544710443301,A,d1,4 +12.777701384288903,A,d2,4 +3.154188215710133,B,d1,4 +2.4545212975960635,B,d2,4 +2.284534141269639,C,d1,4 +3.4115586474605095,C,d2,4 +-0.7744416190640289,D,d1,4 +7.95734682057995,D,d2,4 +3.3770983614013477,A,d1,5 +8.61767085794332,A,d2,5 +0.12254119897458726,B,d1,5 +0.11468021929091354,B,d2,5 +-1.2647252830578548,C,d1,5 +-3.3506493037154055,C,d2,5 +-1.6918095598060048,D,d1,5 +1.3253048725047756,D,d2,5 +5.145425009462966,A,d1,6 +5.73725942229559,A,d2,6 +-2.223309642785237,B,d1,6 +0.48648011474864816,B,d2,6 +-2.2012177614506925,C,d1,6 +1.857075727529136,C,d2,6 +-0.8133054820871612,D,d1,6 +-1.7113560168975663,D,d2,6 +8.397112273554288,A,d1,7 +5.376131243152009,A,d2,7 +1.3669177848374323,B,d1,7 +0.9721548281418051,B,d2,7 +3.8985366050168295,C,d1,7 +5.0750678263487226,C,d2,7 +1.5763379519478005,D,d1,7 +-0.3861128068611285,D,d2,7 +9.648303006727525,A,d1,8 +3.710151996757312,A,d2,8 +5.972807663495972,B,d1,8 +4.350390974281194,B,d2,8 +6.258768605837868,C,d1,8 +3.2105071403214387,C,d2,8 +0.15393124061539032,D,d1,8 +-2.5547763361476363,D,d2,8 +-3.0677265537030856,A,d1,9 +4.359136440390644,A,d2,9 +2.907110623730842,B,d1,9 +4.125411410488164,B,d2,9 +1.9761189694982417,C,d1,9 +3.441883797936557,C,d2,9 +-3.0685326916867455,D,d1,9 +0.054118435162489154,D,d2,9 +13.422777347466306,A,d1,10 +11.210858574151388,A,d2,10 +2.567888661554812,B,d1,10 +2.0304319022284214,B,d2,10 +4.88611278655465,C,d1,10 +6.6320285634018035,C,d2,10 +3.9142760470343623,D,d1,10 +2.311911619953296,D,d2,10 +10.852130694348503,A,d1,11 +14.42127903982665,A,d2,11 +0.1469522649229611,B,d1,11 +0.6032038811808991,B,d2,11 +1.7384554039467177,C,d1,11 +3.7227138685731767,C,d2,11 +4.571523846566923,D,d1,11 +4.649026040495684,D,d2,11 +3.910138496014496,A,d1,12 +6.413750313180211,A,d2,12 +5.807001050879677,B,d1,12 +6.260160795303587,B,d2,12 +1.8520450445342187,C,d1,12 +2.5009282390307,C,d2,12 +1.125568283667134,D,d1,12 +0.8129924247764678,D,d2,12 +12.807794580205472,A,d1,13 +8.322436119924697,A,d2,13 +-0.643452270161581,B,d1,13 +0.12092707191439489,B,d2,13 +3.297069094909194,C,d1,13 +4.742854206617035,C,d2,13 +4.047117851822433,D,d1,13 +0.03296896782164138,D,d2,13 +16.7741439108485,A,d1,14 +12.760981727316295,A,d2,14 +3.025831544500329,B,d1,14 +0.7764413317042818,B,d2,14 +0.7283189557517783,C,d1,14 +-1.681301630849537,C,d2,14 +1.1249346588251992,D,d1,14 +1.6231214727388714,D,d2,14 +1.1246966748387255,A,d1,15 +1.2672197542452492,A,d2,15 +1.4941892508494075,B,d1,15 +1.512177146769281,B,d2,15 +-0.4192343747406144,C,d1,15 +0.5862372477457867,C,d2,15 +5.455303216158969,D,d1,15 +4.850268579460773,D,d2,15 +10.38511257681331,A,d1,16 +3.5594224801002063,A,d2,16 +2.017868297443292,B,d1,16 +3.3160949613203567,B,d2,16 +-1.0531480693202222,C,d1,16 +-0.20796996778768984,C,d2,16 +6.247290182493918,D,d1,16 +2.4417104552202438,D,d2,16 +4.80729810661313,A,d1,17 +3.2628217713572756,A,d2,17 +5.845990666877865,B,d1,17 +2.583367936379729,B,d2,17 +3.3169837345113145,C,d1,17 +-1.9964079746573784,C,d2,17 +4.39487372646855,D,d1,17 +4.157044282085577,D,d2,17 +10.240318518673588,A,d1,18 +14.724152656599722,A,d2,18 +4.865357847811297,B,d1,18 +4.071158435185416,B,d2,18 +-2.116276900225867,C,d1,18 +-3.867495508642045,C,d2,18 +2.870381121395314,D,d1,18 +4.708722201098421,D,d2,18 +4.8562563713220825,A,d1,19 +4.5760071217033005,A,d2,19 +1.6176851722177807,B,d1,19 +2.6617247815087386,B,d2,19 +-1.3799915893055932,C,d1,19 +0.9866728829505078,C,d2,19 +-2.124344897272937,D,d1,19 +-3.130651750605242,D,d2,19 +0.18496358374393562,A,d1,20 +0.9557850624985917,A,d2,20 +0.7288280847524664,B,d1,20 +-0.4653435413372957,B,d2,20 +-4.6925213895237645,C,d1,20 +-3.652115979512705,C,d2,20 +-2.6967213093392153,D,d1,20 +-4.970890111045517,D,d2,20 +18.882415907571957,A,d1,21 +9.129998873762691,A,d2,21 +1.2505737700650539,B,d1,21 +1.8671953191999,B,d2,21 +2.9582298279460426,C,d1,21 +3.2523729228338585,C,d2,21 +8.72277942030761,D,d1,21 +0.07794228444739426,D,d2,21 +5.591890694646271,A,d1,22 +-0.2507794772165646,A,d2,22 +1.5310835263928027,B,d1,22 +2.044698264019736,B,d2,22 +6.801136978998133,C,d1,22 +5.960395462799964,C,d2,22 +2.225244352202252,D,d1,22 +-1.7665234021467722,D,d2,22 +-1.644908989372592,A,d1,23 +4.138929775513601,A,d2,23 +0.5414403712038367,B,d1,23 +1.3474687738265696,B,d2,23 +-1.557993926205957,C,d1,23 +-0.04959539261802259,C,d2,23 +0.33090714708551583,D,d1,23 +7.644973558045834,D,d2,23 +4.372814545327468,A,d1,24 +2.4552865467212563,A,d2,24 +2.867106981327366,B,d1,24 +2.319283001308714,B,d2,24 +2.627484685332814,C,d1,24 +3.192937342625959,C,d2,24 +-3.362245762573469,D,d1,24 +-5.449220541955391,D,d2,24 +7.1001679809270275,A,d1,25 +5.5622476539561605,A,d2,25 +1.1671137090721442,B,d1,25 +3.302995065925057,B,d2,25 +2.1447737535208518,C,d1,25 +2.2562198630023285,C,d2,25 +0.8165695676079928,D,d1,25 +-3.619761855447412,D,d2,25 diff --git a/test/test.jl b/test/test.jl index 3ddab10..5508e26 100644 --- a/test/test.jl +++ b/test/test.jl @@ -289,6 +289,18 @@ include("testdata.jl") fit!(lmm) @test_nowarn show(io, lmm) + # Intercept term in random part + lmm = Metida.LMM(@formula(var~1), df0; + random = Metida.VarEffect(Metida.@covstr(1+formulation|subject))) + @test typeof( lmm.covstr.random[1].coding[:formulation]) <: StatsModels.FullDummyCoding + # Zero term in random part + lmm = Metida.LMM(@formula(var~1), df0; + random = Metida.VarEffect(Metida.@covstr(0+formulation|subject))) + @test typeof( lmm.covstr.random[1].coding[:formulation]) <: StatsModels.FullDummyCoding + # Intercept term in random part and coding + lmm = Metida.LMM(@formula(var~1), df0; + random = Metida.VarEffect(Metida.@covstr(1+formulation|subject), coding = Dict(:formulation => StatsModels.DummyCoding()))) + @test typeof( lmm.covstr.random[1].coding[:formulation]) <: StatsModels.DummyCoding end ################################################################################ # df0 @@ -770,6 +782,57 @@ end @test_nowarn Metida.fit!(lmm; varlinkf = :identity) end +@testset " Model: Augmented covariance " begin + lmm1 = Metida.LMM(@formula(response ~ 1), ftdf3; + repeated = [Metida.VarEffect(Metida.@covstr(r1|subject), Metida.DIAG), Metida.VarEffect(Metida.@covstr(1|subject), Metida.ACOV(Metida.AR))] + ) + Metida.fit!(lmm1) + + lmm2 = Metida.LMM(@formula(response ~ 1), ftdf3; + repeated = [Metida.VarEffect(Metida.@covstr(r1|subject), Metida.ARH)] + ) + Metida.fit!(lmm2) + @test Metida.m2logreml(lmm1) ≈ Metida.m2logreml(lmm2) + + + lmm1 = Metida.LMM(@formula(response ~ 1), ftdf3; + repeated = [Metida.VarEffect(Metida.@covstr(r1|subject), Metida.DIAG), Metida.VarEffect(Metida.@covstr(1|subject), Metida.ACOV(Metida.CS))] + ) + Metida.fit!(lmm1) + + lmm2 = Metida.LMM(@formula(response ~ 1), ftdf3; + repeated = [Metida.VarEffect(Metida.@covstr(r1|subject), Metida.CSH)] + ) + Metida.fit!(lmm2) + @test Metida.m2logreml(lmm1) ≈ Metida.m2logreml(lmm2) + + lmm = Metida.LMM(@formula(response ~ 1), ftdf3; + repeated = [Metida.VarEffect(Metida.@covstr(r1|subject), Metida.DIAG), Metida.VarEffect(Metida.@covstr(1|subject&r2), Metida.ACOV(Metida.AR))] + ) + Metida.fit!(lmm) + @test Metida.m2logreml(lmm) ≈ 800.7606945922405 atol=1E-6 + + + lmm1 = Metida.LMM(@formula(resp ~ 0 + device), devday; + repeated = [Metida.VarEffect(Metida.@covstr(device|subj&day), Metida.UN), + Metida.VarEffect(Metida.@covstr(1|subj&device), Metida.ACOV(Metida.CS))] + ) + Metida.fit!(lmm1) + + lmm2 = Metida.LMM(@formula(resp ~ 0 + device), devday; + repeated = [Metida.VarEffect(Metida.@covstr(device|subj&day), Metida.UN), + Metida.VarEffect(Metida.@covstr(1|subj&device), Metida.ACOV(Metida.AR))] + ) + Metida.fit!(lmm2) + @test Metida.m2logreml(lmm1) ≈ Metida.m2logreml(lmm2) + + io = IOBuffer(); + + @test_nowarn show(io, lmm2) +end + + + @testset " Random " begin lmm = Metida.LMM(@formula(response ~ 1 + factor*time), ftdf2; random = Metida.VarEffect(Metida.@covstr(factor|subject&factor), Metida.DIAG), diff --git a/test/testdata.jl b/test/testdata.jl index 4d6077d..ba1d9d3 100644 --- a/test/testdata.jl +++ b/test/testdata.jl @@ -17,6 +17,7 @@ ftdf3 = CSV.File(path*"/csv/ftdf3.csv"; types = spatdf = CSV.File(path*"/csv/spatialdata.csv"; types = [Int, Int, String, Float64, Float64, Float64, Float64, Float64]) |> DataFrame +devday = CSV.File(path*"/csv/devday.csv"; types = [ Float64, String, String, String]) |> DataFrame dfrdsfda = CSV.File(joinpath(path, "csv", "berds", "rds1.csv"), types = Dict(:PK => Float64, :subject => String, :period => String, :sequence => String, :treatment => String )) |> DataFrame dropmissing!(dfrdsfda)