feat(matlab): add linear days x tDCS mixed-model scenarios (lme_*)
Adds 6 switch cases replicating the paper's linear mixed model success ~ day * tDCS + (1|subject) on the Box-B2(tDCS=1) vs Box-A2(tDCS=0) arm, reporting the days x tDCS interaction, days, and tDCS effects as t/F/p. mergeA2_full reproduces the paper's interaction (F=7.09 vs 7.12, p=0.009 vs 0.008); interpretation is sign-aware and honestly notes our data diverges from the paper (Box-B2 ahead on day 1, gap narrows -- not 'equal on day 1, accumulates'). Adds tLme tests. Suite 31/31. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
function tdcs_lme_report(L, scenario, cfg)
|
||||
%TDCS_LME_REPORT Print + save the days x tDCS linear-mixed-model report.
|
||||
% TDCS_LME_REPORT(L, SCENARIO, CFG) formats the result of TDCS_LME to the
|
||||
% console and to analysis/matlab/results/<SCENARIO>.txt, in the style of the
|
||||
% published result (interaction, days, tDCS effects) plus interpretation and
|
||||
% the paper's reference numbers.
|
||||
|
||||
bar = repmat('=', 1, 78);
|
||||
s = sprintf('%s\n', bar);
|
||||
s = [s sprintf('LINEAR MIXED MODEL (days x tDCS) -- scenario: %s\n', scenario)];
|
||||
s = [s sprintf('%s\n', bar)];
|
||||
s = [s sprintf('model: success ~ day * tDCS + (1|subject) [tDCS: %s = 1 vs %s = 0]\n', ...
|
||||
cfg.anchorHigh, cfg.anchorLow)];
|
||||
s = [s sprintf('N = %d subjects, %d sessions (day used raw: tDCS main = first-day difference)\n\n', ...
|
||||
L.nSubjects, L.nObs)];
|
||||
|
||||
s = [s sprintf('%-27s %-14s %-13s %s\n', 'effect', 't (df)', 'F (df1)', 'p')];
|
||||
s = [s sprintf('%s\n', repmat('-', 1, 70))];
|
||||
s = [s localRow('days x tDCS (interaction)', L.interaction)];
|
||||
s = [s localRow('days (learning)', L.day)];
|
||||
s = [s localRow('tDCS (main, at day 0)', L.tDCS)];
|
||||
|
||||
s = [s sprintf('\nINTERPRETATION\n')];
|
||||
if L.interaction.p >= 0.05
|
||||
interTxt = 'slopes are parallel (no differential change over training)';
|
||||
elseif L.interaction.estimate > 0
|
||||
interTxt = 'the tDCS (Box-B2) group improves FASTER -- benefit ACCUMULATES over training';
|
||||
else
|
||||
interTxt = 'the tDCS (Box-B2) group improves SLOWER -- groups CONVERGE (Box-B2 is ahead early, the gap narrows)';
|
||||
end
|
||||
s = [s sprintf(' - days x tDCS interaction: %s (p=%.4f, slope diff=%.2f) -> %s.\n', ...
|
||||
localSig(L.interaction.p), L.interaction.p, L.interaction.estimate, interTxt)];
|
||||
s = [s sprintf(' - days (learning): %s (p=%.2g) -> performance improves with training.\n', ...
|
||||
localSig(L.day.p), L.day.p)];
|
||||
s = [s sprintf(' - tDCS main effect at day 0: %s (p=%.4f) -> the groups %s on the first day.\n', ...
|
||||
localSig(L.tDCS.p), L.tDCS.p, ...
|
||||
localPick(L.tDCS.p < 0.05, 'already DIFFER', 'are comparable'))];
|
||||
|
||||
s = [s sprintf('\nPaper reference (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008;\n')];
|
||||
s = [s sprintf(' days t(227)=9.64, F(1)=267.64, p=1.2e-18; tDCS t(227)=0.23, F(1)=0.053, p=0.81.\n')];
|
||||
s = [s sprintf(' (Our N and exact statistics differ; this replicates the MODEL FORM on our data.)\n')];
|
||||
|
||||
fprintf('%s', s);
|
||||
|
||||
thisDir = fileparts(mfilename('fullpath'));
|
||||
resDir = fullfile(thisDir, 'results');
|
||||
if ~exist(resDir, 'dir'); mkdir(resDir); end
|
||||
fid = fopen(fullfile(resDir, [scenario '.txt']), 'w');
|
||||
if fid < 0
|
||||
error('tdcs_lme_report:fopen', 'Cannot open results file for "%s".', scenario);
|
||||
end
|
||||
cleanup = onCleanup(@() fclose(fid)); %#ok<NASGU>
|
||||
fprintf(fid, '%s', s);
|
||||
|
||||
end
|
||||
|
||||
function r = localRow(name, e)
|
||||
r = sprintf('%-27s t(%d)=%6.2f F(%d)=%8.3f p=%.4g\n', name, e.df, e.t, e.df1, e.F, e.p);
|
||||
end
|
||||
|
||||
function t = localSig(p)
|
||||
if p < 0.05; t = 'SIGNIFICANT'; else; t = 'n.s.'; end
|
||||
end
|
||||
|
||||
function t = localPick(b, yes, no)
|
||||
if b; t = yes; else; t = no; end
|
||||
end
|
||||
Reference in New Issue
Block a user