Simulation in Julia

How I learned to stop worrying and love the bootstrap

Author

Phillip Alday

Published

May 6, 2022

Recall….

using AlgebraOfGraphics
using CairoMakie
using DataFrames
using GLM
using MixedModels
using MixedModelsMakie
using MixedModelsExtras
using MixedModelsSim
using ProgressMeter
using StatsModels
using StatsBase
using Random


CairoMakie.activate!(; type="svg")
ProgressMeter.ijulia_behavior(:clear);
kb07 = MixedModels.dataset(:kb07)
contrasts = Dict(:subj => Grouping(),
                 :item => Grouping(),
                 :spkr => EffectsCoding(),
                 :prec => EffectsCoding(),
                 :load => EffectsCoding())
form = @formula(rt_trunc ~ 1 + spkr * prec * load +
                          (1 + spkr * prec * load | subj) +
                          (1 + spkr * prec * load | item))
model = fit(MixedModel, form, kb07; contrasts)
Minimizing 1697      Time: 0:00:04 ( 2.66 ms/it)
  objective:  28578.379882306126
Est. SE z p σ_subj σ_item
(Intercept) 2181.8600 76.9837 28.34 <1e-99 301.6141 361.2191
spkr: old 67.7485 19.2522 3.52 0.0004 71.7552 41.6368
prec: maintain -333.9212 47.6946 -7.00 <1e-11 75.0742 249.7744
load: yes 78.5831 21.2565 3.70 0.0002 87.5743 53.7719
spkr: old & prec: maintain -21.7784 20.4371 -1.07 0.2866 95.0200 31.9584
spkr: old & load: yes 18.3844 17.3845 1.06 0.2903 42.6824 38.0149
prec: maintain & load: yes 4.5339 22.4912 0.20 0.8402 86.6206 68.6652
spkr: old & prec: maintain & load: yes 23.4202 21.2220 1.10 0.2698 62.3229 70.7639
Residual 633.7265
model.rePCA
(subj = [0.37031238827926216, 0.6417807855784552, 0.8792429052743644, 0.9999742210400684, 0.9999997919569437, 0.9999999996158602, 1.0, 1.0], item = [0.3557735142771573, 0.6333318296284408, 0.8146986374406038, 0.9481639067412695, 0.9998220284927168, 0.9999998992983445, 1.0, 1.0])
shrinkageplot(model, :subj)

shrinkageplot(model, :item)

rng = MersenneTwister(42)
dat = DataFrame(kb07; copycols=true)

simple_form = @formula(rt_trunc ~ 1 + spkr * prec * load +
                          (1 + spkr + prec + load | subj) +
                          (1 + spkr + prec + load | item))

results = DataFrame()

simple_model = fit(MixedModel, simple_form, kb07; contrasts)

# if doing this yourself, add
# @showprogress
# before the for-loop and get an automatic progress bar
# courtesy of ProgressMeter.jl
for i in 1:100
    refit!(simple_model, simulate(rng, model); progress=false)
    est = DataFrame(coeftable(simple_model))
    est[!, :iter] .= i
    append!(results, est)
end

rename!(results,
        "Name" => "coef",
        "Coef." => "est",
        "Std. Error" => "se",
         "Pr(>|z|)" => "p")
Minimizing 723   Time: 0:00:00 ( 0.52 ms/it)
  objective:  28637.1393507629

800 rows × 6 columns (omitted printing of 1 columns)

coefestsezp
StringFloat64Float64Float64Float64
1(Intercept)2174.2670.853230.68688.54547e-207
2spkr: old68.051920.9113.254370.00113645
3prec: maintain-334.19345.3748-7.365181.76904e-13
4load: yes58.454720.00042.922670.00347044
5spkr: old & prec: maintain-5.9908215.512-0.3862050.699345
6spkr: old & load: yes21.03715.5121.356180.175043
7prec: maintain & load: yes12.303715.5120.793170.427679
8spkr: old & prec: maintain & load: yes14.81815.5120.955260.339446
9(Intercept)2179.6175.868228.7291.65906e-181
10spkr: old80.343720.07744.00176.28895e-5
11prec: maintain-296.96748.7262-6.09461.09708e-9
12load: yes128.86518.84316.838847.98346e-12
13spkr: old & prec: maintain4.5711316.08160.2842460.776222
14spkr: old & load: yes8.514416.08160.529450.596493
15prec: maintain & load: yes-35.197616.0816-2.188690.0286193
16spkr: old & prec: maintain & load: yes7.4980916.08160.4662530.641034
17(Intercept)2189.8772.101830.37191.29155e-202
18spkr: old96.435722.09574.364451.27445e-5
19prec: maintain-353.00150.2821-7.020422.2121e-12
20load: yes65.137823.11012.818580.00482366
21spkr: old & prec: maintain3.7820615.79910.2393840.810808
22spkr: old & load: yes-5.2055115.7991-0.3294820.741792
23prec: maintain & load: yes25.038415.79911.58480.113012
24spkr: old & prec: maintain & load: yes37.795715.79912.392270.0167445
25(Intercept)2186.4681.125526.95155.47511e-160
26spkr: old86.85821.79733.984816.75331e-5
27prec: maintain-329.51649.0542-6.717381.85021e-11
28load: yes88.554820.73634.270511.95025e-5
29spkr: old & prec: maintain-61.277416.0246-3.823960.000131324
30spkr: old & load: yes17.835616.02461.113020.265702
plt = data(results) * mapping(:est; layout=:coef) * AlgebraOfGraphics.density()
draw(plt)

combine(groupby(results, :coef), :est => shortestcovint => :est)

8 rows × 2 columns

coefest
StringTuple…
1(Intercept)(2027.76, 2317.46)
2spkr: old(25.8411, 97.5038)
3prec: maintain(-410.845, -236.202)
4load: yes(29.3886, 114.582)
5spkr: old & prec: maintain(-66.9195, 10.8659)
6spkr: old & load: yes(-8.39011, 58.4824)
7prec: maintain & load: yes(-30.6927, 50.2594)
8spkr: old & prec: maintain & load: yes(-36.9853, 52.137)
combine(groupby(results, :coef),
        :p => (x -> mean(x .< 0.05)) => :percent_significant)

8 rows × 2 columns

coefpercent_significant
StringFloat64
1(Intercept)1.0
2spkr: old0.91
3prec: maintain1.0
4load: yes0.94
5spkr: old & prec: maintain0.34
6spkr: old & load: yes0.3
7prec: maintain & load: yes0.21
8spkr: old & prec: maintain & load: yes0.36