analysis(matlab): per-variation subfolders (grouping x window) for the paper LME
Add make_variations.m + variation_analyze.m generating 20 self-contained subfolders under analysis/matlab/variations/, one per grouping x day-window, each with exactly three files: data.csv (curated subset), analyze.m (a simple standalone script fitting behavior ~ stim + day + stim:day + (1|rat) on the success COUNT), and result.txt (its output). Plus variations/SUMMARY.csv. Groupings (stim=1 / stim=0, other groups dropped): unmerge B2 vs A2 right_only B2+Right vs A2 (Box-A dropped) naive_a2 B2 vs A2+Naive (Right, Box-A dropped) naive_boxa B2 vs A2+Naive+Box-A (Right dropped) Windows: 0-10, 0-13, 0-5, 6-10, 6-13. All 20 have equal day coverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
% Variation analysis -- the paper's linear mixed model on the successful-reach
|
||||
% COUNT, fit on this folder's curated data subset.
|
||||
%
|
||||
% model: behavior ~ stim + day + stim:day + (1|rat)
|
||||
% behavior = successful reaches (count per session)
|
||||
% stim = 1 for the treatment group(s), 0 for the control group(s)
|
||||
% day = training day within this window (0 = first analyzed day)
|
||||
% rat = subject (random intercept)
|
||||
%
|
||||
% Self-contained: reads data.csv beside this script and writes result.txt.
|
||||
% Run headless from this folder with: matlab -batch "analyze"
|
||||
% (This is a copy of analysis/matlab/variation_analyze.m; see make_variations.m.)
|
||||
|
||||
here = fileparts(mfilename('fullpath'));
|
||||
if isempty(here); here = pwd; end
|
||||
vname = regexprep(here, '.*[/\\]', ''); % folder name = variation id
|
||||
|
||||
D = readtable(fullfile(here, 'data.csv'), 'TextType', 'string');
|
||||
|
||||
tbl = table(D.success, D.day - min(D.day), double(D.stim), categorical(D.subject), ...
|
||||
'VariableNames', {'behavior', 'day', 'stim', 'rat'});
|
||||
m = fitlme(tbl, 'behavior ~ stim + day + stim:day + (1|rat)');
|
||||
C = m.Coefficients; A = anova(m); ci = coefCI(m);
|
||||
|
||||
gi = @(t) find(strcmp(C.Name, t), 1);
|
||||
ga = @(t) find(strcmp(A.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%8.3f p=%.4g\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)));
|
||||
|
||||
maxT = max(D.day(D.stim == 1)); minT = min(D.day(D.stim == 1));
|
||||
maxC = max(D.day(D.stim == 0)); minC = min(D.day(D.stim == 0));
|
||||
if abs(maxT - maxC) > 2
|
||||
cov = '** WARNING: unequal day coverage -- interaction may be confounded. **';
|
||||
else
|
||||
cov = '(equal day coverage over this window)';
|
||||
end
|
||||
|
||||
ii = gi('day:stim'); pI = C.pValue(ii); eI = C.Estimate(ii);
|
||||
if pI >= 0.05
|
||||
verdict = 'n.s. -- slopes parallel (no differential learning rate)';
|
||||
elseif eI > 0
|
||||
verdict = 'SIGNIFICANT positive -- treatment improves FASTER (benefit accumulates)';
|
||||
else
|
||||
verdict = 'SIGNIFICANT negative -- treatment improves SLOWER (groups converge)';
|
||||
end
|
||||
|
||||
bar = repmat('=', 1, 78);
|
||||
raw = regexprep(evalc('disp(m)'), '</?strong>', '');
|
||||
s = sprintf('%s\nVARIATION: %s\n%s\n', bar, vname, bar);
|
||||
s = [s sprintf('model: behavior ~ stim + day + stim:day + (1|rat) (behavior = success COUNT)\n')];
|
||||
s = [s sprintf('day = training day within window (0 = first analyzed day)\n')];
|
||||
s = [s sprintf('treatment (stim=1): %s\n', strjoin(cellstr(unique(D.group(D.stim == 1))), ', '))];
|
||||
s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim == 0))), ', '))];
|
||||
s = [s sprintf('N = %d rats, %d sessions raw day coverage: treat %d..%d, control %d..%d\n', ...
|
||||
numel(unique(D.subject)), height(D), minT, maxT, minC, maxC)];
|
||||
s = [s sprintf('%s\n\n%s\nFULL MODEL SUMMARY -- fitlme\n%s\n%s\n', cov, bar, bar, raw)];
|
||||
s = [s sprintf('%-26s %-13s %-13s %s\n%s\n', 'effect', 't (df)', 'F (df1)', 'p', repmat('-', 1, 66))];
|
||||
s = [s row('stim x day (interaction)', 'day:stim')];
|
||||
s = [s row('day (learning)', 'day')];
|
||||
s = [s row('stim (main, window start)', 'stim')];
|
||||
s = [s sprintf('interaction 95%% CI: [%+.2f, %+.2f]\n', ci(ii, 1), ci(ii, 2))];
|
||||
s = [s sprintf('INTERPRETATION: stim x day interaction %s (p=%.4g, slope diff=%+.2f)\n', verdict, pI, eI)];
|
||||
s = [s sprintf('Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.\n')];
|
||||
|
||||
fprintf('%s', s);
|
||||
fid = fopen(fullfile(here, 'result.txt'), 'w');
|
||||
fprintf(fid, '%s', s);
|
||||
fclose(fid);
|
||||
|
||||
% Machine-readable handoff for the summary table (see make_variations.m).
|
||||
VARRESULT = struct('name', vname, 'nRats', numel(unique(D.subject)), ...
|
||||
'nObs', height(D), 'interP', pI, 'interEst', eI, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
@@ -0,0 +1,35 @@
|
||||
subject,group,day,success,total,stim
|
||||
Banh-mi-1,Electrode-Box-B2,6,90,131,1
|
||||
Banh-mi-1,Electrode-Box-B2,7,109,148,1
|
||||
Banh-mi-1,Electrode-Box-B2,8,104,137,1
|
||||
Banh-mi-1,Electrode-Box-B2,9,119,150,1
|
||||
Banh-mi-1,Electrode-Box-B2,10,121,158,1
|
||||
Banh-mi-1,Electrode-Box-B2,11,121,148,1
|
||||
Banh-mi-1,Electrode-Box-B2,12,120,149,1
|
||||
Banh-mi-1,Electrode-Box-B2,13,135,154,1
|
||||
Banh-mi-2,Electrode-Box-A2,6,74,146,0
|
||||
Banh-mi-2,Electrode-Box-A2,7,70,148,0
|
||||
Banh-mi-2,Electrode-Box-A2,8,65,130,0
|
||||
Banh-mi-2,Electrode-Box-A2,9,79,151,0
|
||||
Banh-mi-2,Electrode-Box-A2,10,93,152,0
|
||||
Egg-tart-1,Electrode-Box-B2,6,71,142,1
|
||||
Egg-tart-1,Electrode-Box-B2,7,79,138,1
|
||||
Egg-tart-1,Electrode-Box-B2,8,98,142,1
|
||||
Egg-tart-1,Electrode-Box-B2,9,89,139,1
|
||||
Egg-tart-1,Electrode-Box-B2,10,96,143,1
|
||||
Egg-tart-1,Electrode-Box-B2,11,96,148,1
|
||||
Egg-tart-1,Electrode-Box-B2,12,101,156,1
|
||||
Egg-tart-1,Electrode-Box-B2,13,103,152,1
|
||||
Egg-tart-2,Electrode-Box-A2,6,85,145,0
|
||||
Egg-tart-2,Electrode-Box-A2,7,79,143,0
|
||||
Egg-tart-2,Electrode-Box-A2,8,76,131,0
|
||||
Egg-tart-2,Electrode-Box-A2,9,88,149,0
|
||||
Egg-tart-2,Electrode-Box-A2,10,81,151,0
|
||||
Egg-tart-2,Electrode-Box-A2,11,78,152,0
|
||||
Egg-tart-2,Electrode-Box-A2,12,96,155,0
|
||||
Egg-tart-2,Electrode-Box-A2,13,84,155,0
|
||||
Root-beer-1,Electrode-Box-B2,6,104,139,1
|
||||
Root-beer-1,Electrode-Box-B2,7,98,148,1
|
||||
Root-beer-1,Electrode-Box-B2,8,81,145,1
|
||||
Root-beer-1,Electrode-Box-B2,9,89,156,1
|
||||
Root-beer-1,Electrode-Box-B2,10,105,158,1
|
||||
|
@@ -0,0 +1,65 @@
|
||||
==============================================================================
|
||||
VARIATION: unmerge_d6_13
|
||||
==============================================================================
|
||||
model: behavior ~ stim + day + stim:day + (1|rat) (behavior = success COUNT)
|
||||
day = training day within window (0 = first analyzed day)
|
||||
treatment (stim=1): Electrode-Box-B2
|
||||
control (stim=0): Electrode-Box-A2
|
||||
N = 5 rats, 34 sessions raw day coverage: treat 6..13, control 6..13
|
||||
(equal day coverage over this window)
|
||||
|
||||
==============================================================================
|
||||
FULL MODEL SUMMARY -- fitlme
|
||||
==============================================================================
|
||||
|
||||
Linear mixed-effects model fit by ML
|
||||
|
||||
Model information:
|
||||
Number of observations 34
|
||||
Fixed effects coefficients 4
|
||||
Random effects coefficients 5
|
||||
Covariance parameters 2
|
||||
|
||||
Formula:
|
||||
behavior ~ 1 + day*stim + (1 | rat)
|
||||
|
||||
Model fit statistics:
|
||||
AIC BIC LogLikelihood Deviance
|
||||
257.04 266.2 -122.52 245.04
|
||||
|
||||
Fixed effects coefficients (95% CIs):
|
||||
Name Estimate SE tStat DF pValue
|
||||
{'(Intercept)'} 75.17 6.2311 12.064 30 4.8879e-13
|
||||
{'day' } 1.7101 1.061 1.6117 30 0.11749
|
||||
{'stim' } 13.563 8.0252 1.69 30 0.1014
|
||||
{'day:stim' } 2.267 1.3237 1.7126 30 0.097101
|
||||
|
||||
|
||||
Lower Upper
|
||||
62.445 87.896
|
||||
-0.45682 3.877
|
||||
-2.8271 29.952
|
||||
-0.43635 4.9703
|
||||
|
||||
Random effects covariance parameters (95% CIs):
|
||||
Group: rat (5 Levels)
|
||||
Name1 Name2 Type Estimate
|
||||
{'(Intercept)'} {'(Intercept)'} {'std'} 7.1166
|
||||
|
||||
|
||||
Lower Upper
|
||||
3.4834 14.539
|
||||
|
||||
Group: Error
|
||||
Name Estimate Lower Upper
|
||||
{'Res Std'} 7.7328 5.9847 9.9914
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(30)= 1.71 F(1)= 2.933 p=0.0971
|
||||
day (learning) t(30)= 1.61 F(1)= 2.598 p=0.1175
|
||||
stim (main, window start) t(30)= 1.69 F(1)= 2.856 p=0.1014
|
||||
interaction 95% CI: [-0.44, +4.97]
|
||||
INTERPRETATION: stim x day interaction n.s. -- slopes parallel (no differential learning rate) (p=0.0971, slope diff=+2.27)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
Reference in New Issue
Block a user