Calculate group averages
using UnfoldBIDS, PyMNE
using Unfold
using DataFrames
using Statistics
using CairoMakie, AlgebraOfGraphics
using LazyArtifacts CondaPkg Found dependencies: /home/runner/.julia/packages/CondaPkg/8GjrP/CondaPkg.toml
CondaPkg Found dependencies: /home/runner/.julia/packages/PyMNE/cNGDN/CondaPkg.toml
CondaPkg Found dependencies: /home/runner/.julia/packages/PythonCall/83z4q/CondaPkg.toml
CondaPkg Initialising pixi
│ /home/runner/.julia/artifacts/cefba4912c2b400756d043a2563ef77a0088866b/bin/pixi
│ init
│ --format pixi
└ /home/runner/work/UnfoldBIDS.jl/UnfoldBIDS.jl/docs/.CondaPkg
✔ Created /home/runner/work/UnfoldBIDS.jl/UnfoldBIDS.jl/docs/.CondaPkg/pixi.toml
CondaPkg Wrote /home/runner/work/UnfoldBIDS.jl/UnfoldBIDS.jl/docs/.CondaPkg/pixi.toml
│ [dependencies]
│ openssl = ">=3, <3.6"
│ libstdcxx = ">=3.4,<15.0"
│ uv = ">=0.4"
│ libstdcxx-ng = ">=3.4,<15.0"
│
│ [dependencies.python]
│ channel = "conda-forge"
│ build = "*cp*"
│ version = ">=3.10,!=3.14.0,!=3.14.1,<4, >=3.4,<4"
│
│ [project]
│ name = ".CondaPkg"
│ platforms = ["linux-64"]
│ channels = ["conda-forge", "anaconda"]
│ channel-priority = "strict"
│ description = "automatically generated by CondaPkg.jl"
│
│ [pypi-dependencies]
└ mne = ">=1.4"
CondaPkg Installing packages
│ /home/runner/.julia/artifacts/cefba4912c2b400756d043a2563ef77a0088866b/bin/pixi
│ install
└ --manifest-path /home/runner/work/UnfoldBIDS.jl/UnfoldBIDS.jl/docs/.CondaPkg/pixi.toml
✔ The default environment has been installed.Analysis
First let's redo the steps from the quickstart tutorial
sample_data_path = UnfoldBIDS.erp_core_example();
layout_df = bids_layout(sample_data_path, derivatives=false);
data_df = load_bids_eeg_data(layout_df);
33.3%┣██████████████▍ ┫ 1/3 [00:00<Inf:Inf, InfGs/it]
66.7%┣████████████████████████████████ ┫ 2/3 [00:00<00:00, 2it/s]
100.0%┣███████████████████████████████████████████████┫ 3/3 [00:01<00:00, 4it/s]Calculate results
basisfunction = firbasis(τ=(-0.2,.8),sfreq=1024)
f = @formula 0~1
bfDict = ["stimulus"=>(f,basisfunction)]
UnfoldBIDS.rename_to_latency(data_df, :sample); # Unfold expects a :latency collumn in your events; if your event latency is named differently you can use this function as remedy
resultsAll = run_unfold(data_df, bfDict; eventcolumn="trial_type");
33.3%┣██████████████▍ ┫ 1/3 [00:00<Inf:Inf, InfGs/it]
Progress: 6%|██▌ | ETA: 0:00:06
Progress: 36%|██████████████▉ | ETA: 0:00:02
Progress: 85%|██████████████████████████████████▊ | ETA: 0:00:00
Progress: 100%|█████████████████████████████████████████| Time: 0:00:01
66.7%┣████████████████████████████████ ┫ 2/3 [00:08<00:08, 8s/it]
Progress: 64%|██████████████████████████▏ | ETA: 0:00:00
Progress: 100%|█████████████████████████████████████████| Time: 0:00:00
100.0%┣███████████████████████████████████████████████┫ 3/3 [00:09<00:00, 5s/it]
Progress: 6%|██▌ | ETA: 0:00:09
Progress: 76%|███████████████████████████████ | ETA: 0:00:00
Progress: 100%|█████████████████████████████████████████| Time: 0:00:00Now, let's transform the data into a tidier format (Note: We use raw data without a high-pass filter here so estimates will be quite off)
tidy_df = unpack_results(bids_coeftable(resultsAll))
first(tidy_df, 5)5×11 DataFrame
| Row | subject | ses | task | run | channel | coefname | estimate | eventname | group | stderror | time |
|---|---|---|---|---|---|---|---|---|---|---|---|
| SubStrin… | Missing | SubStrin… | Missing | Int64 | String | Float64 | String | Nothing | Nothing | Float64 | |
| 1 | 001 | missing | P3 | missing | 1 | (Intercept) | -17604.5 | stimulus | -0.200195 | ||
| 2 | 001 | missing | P3 | missing | 2 | (Intercept) | -3162.93 | stimulus | -0.200195 | ||
| 3 | 001 | missing | P3 | missing | 3 | (Intercept) | 11587.9 | stimulus | -0.200195 | ||
| 4 | 001 | missing | P3 | missing | 4 | (Intercept) | -1056.33 | stimulus | -0.200195 | ||
| 5 | 001 | missing | P3 | missing | 5 | (Intercept) | -480.149 | stimulus | -0.200195 |
Calculate average over subjects
mean_df = combine(groupby(tidy_df, [:time, :coefname]), :estimate => mean)
first(mean_df, 5)5×3 DataFrame
| Row | time | coefname | estimate_mean |
|---|---|---|---|
| Float64 | String | Float64 | |
| 1 | -0.200195 | (Intercept) | -5304.91 |
| 2 | -0.199219 | (Intercept) | -5304.87 |
| 3 | -0.198242 | (Intercept) | -5304.87 |
| 4 | -0.197266 | (Intercept) | -5304.96 |
| 5 | -0.196289 | (Intercept) | -5305.04 |
Importantly, the above can be extended to groupbyan arbitrary number of covariates!
Plot results using AOG
plt = data(mean_df) * mapping(:time, :estimate_mean, color = :coefname, group=:coefname => nonnumeric) * visual(Lines)
draw(plt, axis=(yticklabelsvisible=false,))
This page was generated using Literate.jl.