Calculate group averages
using UnfoldBIDS
using Unfold
using DataFrames
using Statistics
using CairoMakie, AlgebraOfGraphics
using LazyArtifacts
using Main: @artifact_str # this is a workaround for Artifacts used in docs; locally you would `using LazyArtifacts`
First let's redo the steps from the quickstart
sample_data_path = artifact"sample_BIDS"
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:30
Progress: 88%|████████████████████████████████████ | ETA: 0:00:00
Progress: 100%|█████████████████████████████████████████| Time: 0:00:02
66.7%┣███████████████████████████████▍ ┫ 2/3 [00:12<00:12, 12s/it]
Progress: 55%|██████████████████████▍ | ETA: 0:00:00
Progress: 100%|█████████████████████████████████████████| Time: 0:00:00
100.0%┣███████████████████████████████████████████████┫ 3/3 [00:12<00:00, 6s/it]
Progress: 9%|███▊ | ETA: 0:00:04
Progress: 79%|████████████████████████████████▎ | ETA: 0:00:00
Progress: 100%|█████████████████████████████████████████| Time: 0:00:00
Now 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, 10)
10×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/eeg/sub-001 | missing | P3 | missing | 1 | (Intercept) | -17604.5 | stimulus | -0.200195 | ||
2 | 001/eeg/sub-001 | missing | P3 | missing | 2 | (Intercept) | -3162.93 | stimulus | -0.200195 | ||
3 | 001/eeg/sub-001 | missing | P3 | missing | 3 | (Intercept) | 11587.9 | stimulus | -0.200195 | ||
4 | 001/eeg/sub-001 | missing | P3 | missing | 4 | (Intercept) | -1056.33 | stimulus | -0.200195 | ||
5 | 001/eeg/sub-001 | missing | P3 | missing | 5 | (Intercept) | -480.149 | stimulus | -0.200195 | ||
6 | 001/eeg/sub-001 | missing | P3 | missing | 6 | (Intercept) | 4810.69 | stimulus | -0.200195 | ||
7 | 001/eeg/sub-001 | missing | P3 | missing | 7 | (Intercept) | -6122.02 | stimulus | -0.200195 | ||
8 | 001/eeg/sub-001 | missing | P3 | missing | 8 | (Intercept) | 1359.74 | stimulus | -0.200195 | ||
9 | 001/eeg/sub-001 | missing | P3 | missing | 9 | (Intercept) | -5894.42 | stimulus | -0.200195 | ||
10 | 001/eeg/sub-001 | missing | P3 | missing | 10 | (Intercept) | -8456.68 | 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 groupby
an 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.