feat(matlab): add Satterthwaite DF + honest random-slope test to LME reports
Every fitlme-based report (lme_*, paper_*, phase_*, and the variations' analyze.m) now shows, per effect: residual-DF p, Satterthwaite-DF p, and -- for the interaction -- an HONEST test from a per-animal random-SLOPE model (day|rat), whose Satterthwaite DF collapses toward the animal count. New: tdcs_random_slope_interaction.m (shared helper). Wired into tdcs_lme, tdcs_paper_lme, tdcs_phase_lme, variation_analyze; SUMMARY.csv gains interaction_p_satt / interaction_p_rs. Regenerated all results/, variations/, matched-effort outputs. Key point this surfaces: Satterthwaite ~= residual on the random-INTERCEPT model (the slope's error is at session level), so it does NOT fix pseudoreplication; the random-slope model does. Effect: full-range mergeA2 interaction 0.009 -> 0.75 (collapses); unmerge_d0_5 0.015 -> 0.13 (n.s.); the pooled-control early windows survive honestly (naive_a2_d0_5 0.001 -> 0.028; naive_boxa_d0_5 0.003 -> 0.036). Suite 42/42. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,21 +1,21 @@
|
||||
variation,grouping,window,nRats,nObs,covEqual,interaction_p,interaction_est,stim_p,day_p
|
||||
unmerge_d0_10,unmerge,d0_10,6,61,1,0.142831730250263,1.55766564374789,0.497389134925754,2.83166776054496e-14
|
||||
unmerge_d0_13,unmerge,d0_13,6,70,1,0.1037612192755,1.54665472676189,0.343602740986316,3.0346358823857e-13
|
||||
unmerge_d0_5,unmerge,d0_5,6,36,1,0.015149263054839,5.36190476190475,0.688839435920596,1.57055423419133e-07
|
||||
unmerge_d6_10,unmerge,d6_10,5,25,1,0.485980598616448,1.76666666666666,0.0975215172907211,0.227259314093653
|
||||
unmerge_d6_13,unmerge,d6_13,5,34,1,0.0971009786566259,2.26696773140328,0.101395665857404,0.117493504965036
|
||||
right_only_d0_10,right_only,d0_10,7,72,1,0.072180139606096,1.73004431141938,0.715879551990348,5.94289273347193e-16
|
||||
right_only_d0_13,right_only,d0_13,7,84,1,0.0480416099228058,1.7001712792199,0.528517264593511,1.17078898575779e-14
|
||||
right_only_d0_5,right_only,d0_5,7,42,1,0.00589730538358453,5.30714285714286,0.469556667463413,1.45827052706827e-08
|
||||
right_only_d6_10,right_only,d6_10,6,30,1,0.288979620167748,2.425,0.119238243812818,0.200957769624237
|
||||
right_only_d6_13,right_only,d6_13,6,42,1,0.0258497485171371,2.75792254325755,0.109557181635453,0.0976080018855909
|
||||
naive_a2_d0_10,naive_a2,d0_10,10,104,1,0.125891264174292,1.43371876298297,0.141836960529428,1.59796354184479e-27
|
||||
naive_a2_d0_13,naive_a2,d0_13,10,124,1,0.0397967517409217,1.61366204723722,0.153633906173184,2.5469330031931e-28
|
||||
naive_a2_d0_5,naive_a2,d0_5,10,59,1,0.00107331575782455,6.96223661591522,0.960550975833492,1.1254222201539e-09
|
||||
naive_a2_d6_10,naive_a2,d6_10,9,45,1,0.449922139297732,-1.8,0.00929038977362001,8.02730473236241e-05
|
||||
naive_a2_d6_13,naive_a2,d6_13,9,65,1,0.439759713746994,1.15527349799111,0.0165675905421826,0.00123453301903328
|
||||
naive_boxa_d0_10,naive_boxa,d0_10,11,115,1,0.194116831474294,1.17792772470162,0.124842156542362,1.7431506758907e-32
|
||||
naive_boxa_d0_13,naive_boxa,d0_13,11,138,1,0.0848056366333164,1.30637615965008,0.140502409490992,1.21292542612342e-34
|
||||
naive_boxa_d0_5,naive_boxa,d0_5,11,65,1,0.00254470765200637,6.40329932104724,0.881419104187055,2.50618640106882e-11
|
||||
naive_boxa_d6_10,naive_boxa,d6_10,10,50,1,0.46817073850354,-1.61904761904762,0.014689379915428,1.87688778586107e-05
|
||||
naive_boxa_d6_13,naive_boxa,d6_13,10,73,1,0.530807487326757,0.873689202983884,0.0303916991304334,6.44631091768978e-05
|
||||
variation,grouping,window,nRats,nObs,covEqual,interaction_p,interaction_p_satt,interaction_p_rs,interaction_est,stim_p,day_p
|
||||
unmerge_d0_10,unmerge,d0_10,6,61,1,0.142831730250263,0.142797566084653,0.247946685371652,1.55766564374789,0.497389134925754,2.83166776054496e-14
|
||||
unmerge_d0_13,unmerge,d0_13,6,70,1,0.1037612192755,0.103490077847449,0.222686826261486,1.54665472676189,0.343602740986316,3.0346358823857e-13
|
||||
unmerge_d0_5,unmerge,d0_5,6,36,1,0.015149263054839,0.0154996899553134,0.133145634512884,5.36190476190475,0.688839435920596,1.57055423419133e-07
|
||||
unmerge_d6_10,unmerge,d6_10,5,25,1,0.485980598616448,0.486366669144796,0.554919025308352,1.76666666666666,0.0975215172907211,0.227259314093653
|
||||
unmerge_d6_13,unmerge,d6_13,5,34,1,0.0971009786566259,0.0970128901807668,0.13816578257917,2.26696773140328,0.101395665857404,0.117493504965036
|
||||
right_only_d0_10,right_only,d0_10,7,72,1,0.072180139606096,0.0721794737454714,0.124574209202325,1.73004431141938,0.715879551990348,5.94289273347193e-16
|
||||
right_only_d0_13,right_only,d0_13,7,84,1,0.0480416099228058,0.0478799998667326,0.102857124294903,1.7001712792199,0.528517264593511,1.17078898575779e-14
|
||||
right_only_d0_5,right_only,d0_5,7,42,1,0.00589730538358453,0.00612750828678172,0.0876259332262465,5.30714285714286,0.469556667463413,1.45827052706827e-08
|
||||
right_only_d6_10,right_only,d6_10,6,30,1,0.288979620167748,0.289798539517805,0.378365014630273,2.425,0.119238243812818,0.200957769624237
|
||||
right_only_d6_13,right_only,d6_13,6,42,1,0.0258497485171371,0.0259134063416617,0.0369743190514673,2.75792254325755,0.109557181635453,0.0976080018855909
|
||||
naive_a2_d0_10,naive_a2,d0_10,10,104,1,0.125891264174292,0.126071775330177,0.30932733005532,1.43371876298297,0.141836960529428,1.59796354184479e-27
|
||||
naive_a2_d0_13,naive_a2,d0_13,10,124,1,0.0397967517409217,0.0398599319703312,0.0578149015961064,1.61366204723722,0.153633906173184,2.5469330031931e-28
|
||||
naive_a2_d0_5,naive_a2,d0_5,10,59,1,0.00107331575782455,0.00115218904921896,0.028152310883297,6.96223661591522,0.960550975833492,1.1254222201539e-09
|
||||
naive_a2_d6_10,naive_a2,d6_10,9,45,1,0.449922139297732,0.450525162691322,0.522263670801849,-1.8,0.00929038977362001,8.02730473236241e-05
|
||||
naive_a2_d6_13,naive_a2,d6_13,9,65,1,0.439759713746994,0.439915577313227,0.563543413702517,1.15527349799111,0.0165675905421826,0.00123453301903328
|
||||
naive_boxa_d0_10,naive_boxa,d0_10,11,115,1,0.194116831474294,0.194284662755081,0.383551190839722,1.17792772470162,0.124842156542362,1.7431506758907e-32
|
||||
naive_boxa_d0_13,naive_boxa,d0_13,11,138,1,0.0848056366333164,0.0848864932608599,0.140324990567599,1.30637615965008,0.140502409490992,1.21292542612342e-34
|
||||
naive_boxa_d0_5,naive_boxa,d0_5,11,65,1,0.00254470765200637,0.00267934065308424,0.0356145839564805,6.40329932104724,0.881419104187055,2.50618640106882e-11
|
||||
naive_boxa_d6_10,naive_boxa,d6_10,10,50,1,0.46817073850354,0.468724498567948,0.534407300553877,-1.61904761904762,0.014689379915428,1.87688778586107e-05
|
||||
naive_boxa_d6_13,naive_boxa,d6_13,10,73,1,0.530807487326757,0.530942127564996,0.696589180707779,0.873689202983884,0.0303916991304334,6.44631091768978e-05
|
||||
|
||||
|
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 8.5397 6.1599 11.839
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(20)= 3.27 F(1)= 10.700 p=0.003822
|
||||
day (learning) t(20)= 2.89 F(1)= 8.337 p=0.009105
|
||||
stim (main, window start) t(20)= -1.42 F(1)= 2.025 p=0.1701
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(20)= 3.27 F(1)= 10.700 p=0.003822 p=0.004244 (df=18)
|
||||
day (learning) t(20)= 2.89 F(1)= 8.337 p=0.009105 p=0.009807 (df=18)
|
||||
stim (main, window start) t(20)= -1.42 F(1)= 2.025 p=0.1701 p=0.1703 (df=20)
|
||||
interaction 95% CI: [+3.70, +16.70]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,9.8)=9.76, p=0.01107
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction SIGNIFICANT positive -- treatment improves FASTER (benefit accumulates) (p=0.003822, slope diff=+10.20)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 13.78 11.942 15.902
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(100)= 1.54 F(1)= 2.382 p=0.1259
|
||||
day (learning) t(100)= 15.09 F(1)= 227.710 p=1.598e-27
|
||||
stim (main, window start) t(100)= 1.48 F(1)= 2.192 p=0.1418
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(100)= 1.54 F(1)= 2.382 p=0.1259 p=0.1261 (df=95)
|
||||
day (learning) t(100)= 15.09 F(1)=227.710 p=1.598e-27 p=4.059e-27 (df=96)
|
||||
stim (main, window start) t(100)= 1.48 F(1)= 2.192 p=0.1418 p=0.1543 (df=20)
|
||||
interaction 95% CI: [-0.41, +3.28]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,9.0)=1.16, p=0.3093
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction n.s. -- slopes parallel (no differential learning rate) (p=0.1259, slope diff=+1.43)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 15.264 13.405 17.381
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(120)= 2.08 F(1)= 4.320 p=0.0398
|
||||
day (learning) t(120)= 14.57 F(1)= 212.424 p=2.547e-28
|
||||
stim (main, window start) t(120)= 1.44 F(1)= 2.062 p=0.1536
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(120)= 2.08 F(1)= 4.320 p=0.0398 p=0.03986 (df=117)
|
||||
day (learning) t(120)= 14.57 F(1)=212.424 p=2.547e-28 p=3.246e-28 (df=119)
|
||||
stim (main, window start) t(120)= 1.44 F(1)= 2.062 p=0.1536 p=0.1655 (df=21)
|
||||
interaction 95% CI: [+0.08, +3.15]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,41.7)=3.81, p=0.05781
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction SIGNIFICANT positive -- treatment improves FASTER (benefit accumulates) (p=0.0398, slope diff=+1.61)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -34,7 +50,7 @@ if abs(maxT - maxC) > 2
|
||||
else
|
||||
cov = '(equal day coverage over this window)';
|
||||
end
|
||||
y
|
||||
|
||||
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)';
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -28,27 +28,41 @@ Model fit statistics:
|
||||
489.28 501.74 -238.64 477.28
|
||||
|
||||
Fixed effects coefficients (95% CIs):
|
||||
Name Estimate SE tStat DF pValue Lower Upper
|
||||
{'(Intercept)'} 9.0584 5.0267 1.8021 55 0.077018 -1.0153 19.132
|
||||
{'day' } 8.2568 1.1279 7.3206 55 1.1254e-09 5.9965 10.517
|
||||
{'stim' } 0.44958 9.048 0.049688 55 0.96055 -17.683 18.582
|
||||
{'day:stim' } 6.9622 2.0162 3.4532 55 0.0010733 2.9217 11.003
|
||||
Name Estimate SE tStat DF pValue
|
||||
{'(Intercept)'} 9.0584 5.0267 1.8021 55 0.077018
|
||||
{'day' } 8.2568 1.1279 7.3206 55 1.1254e-09
|
||||
{'stim' } 0.44958 9.048 0.049688 55 0.96055
|
||||
{'day:stim' } 6.9622 2.0162 3.4532 55 0.0010733
|
||||
|
||||
|
||||
Lower Upper
|
||||
-1.0153 19.132
|
||||
5.9965 10.517
|
||||
-17.683 18.582
|
||||
2.9217 11.003
|
||||
|
||||
Random effects covariance parameters (95% CIs):
|
||||
Group: rat (10 Levels)
|
||||
Name1 Name2 Type Estimate Lower Upper
|
||||
{'(Intercept)'} {'(Intercept)'} {'std'} 9.6432 5.5002 16.907
|
||||
Name1 Name2 Type Estimate
|
||||
{'(Intercept)'} {'(Intercept)'} {'std'} 9.6432
|
||||
|
||||
|
||||
Lower Upper
|
||||
5.5002 16.907
|
||||
|
||||
Group: Error
|
||||
Name Estimate Lower Upper
|
||||
{'Res Std'} 12.109 9.9317 14.763
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(55)= 3.45 F(1)= 11.924 p=0.001073
|
||||
day (learning) t(55)= 7.32 F(1)= 53.591 p=1.125e-09
|
||||
stim (main, window start) t(55)= 0.05 F(1)= 0.002 p=0.9606
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(55)= 3.45 F(1)= 11.924 p=0.001073 p=0.001152 (df=49)
|
||||
day (learning) t(55)= 7.32 F(1)= 53.591 p=1.125e-09 p=2.092e-09 (df=49)
|
||||
stim (main, window start) t(55)= 0.05 F(1)= 0.002 p=0.9606 p=0.9609 (df=20)
|
||||
interaction 95% CI: [+2.92, +11.00]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,9.7)=6.65, p=0.02815
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction SIGNIFICANT positive -- treatment improves FASTER (benefit accumulates) (p=0.001073, slope diff=+6.96)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 10.552 8.376 13.294
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(41)= -0.76 F(1)= 0.582 p=0.4499
|
||||
day (learning) t(41)= 4.38 F(1)= 19.183 p=8.027e-05
|
||||
stim (main, window start) t(41)= 2.73 F(1)= 7.453 p=0.00929
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(41)= -0.76 F(1)= 0.582 p=0.4499 p=0.4505 (df=36)
|
||||
day (learning) t(41)= 4.38 F(1)= 19.183 p=8.027e-05 p=9.813e-05 (df=36)
|
||||
stim (main, window start) t(41)= 2.73 F(1)= 7.453 p=0.00929 p=0.01541 (df=15)
|
||||
interaction 95% CI: [-6.57, +2.97]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,9.0)=0.44, p=0.5223
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction n.s. -- slopes parallel (no differential learning rate) (p=0.4499, slope diff=-1.80)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 12.033 10.004 14.473
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(61)= 0.78 F(1)= 0.605 p=0.4398
|
||||
day (learning) t(61)= 3.39 F(1)= 11.485 p=0.001235
|
||||
stim (main, window start) t(61)= 2.46 F(1)= 6.072 p=0.01657
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(61)= 0.78 F(1)= 0.605 p=0.4398 p=0.4399 (df=58)
|
||||
day (learning) t(61)= 3.39 F(1)= 11.485 p=0.001235 p=0.001274 (df=57)
|
||||
stim (main, window start) t(61)= 2.46 F(1)= 6.072 p=0.01657 p=0.02473 (df=17)
|
||||
interaction 95% CI: [-1.82, +4.13]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,7.7)=0.36, p=0.5635
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction n.s. -- slopes parallel (no differential learning rate) (p=0.4398, slope diff=+1.16)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 13.706 11.962 15.704
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(111)= 1.31 F(1)= 1.707 p=0.1941
|
||||
day (learning) t(111)= 16.91 F(1)= 285.824 p=1.743e-32
|
||||
stim (main, window start) t(111)= 1.55 F(1)= 2.392 p=0.1248
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(111)= 1.31 F(1)= 1.707 p=0.1941 p=0.1943 (df=104)
|
||||
day (learning) t(111)= 16.91 F(1)=285.824 p=1.743e-32 p=6.758e-32 (df=106)
|
||||
stim (main, window start) t(111)= 1.55 F(1)= 2.392 p=0.1248 p=0.1361 (df=22)
|
||||
interaction 95% CI: [-0.61, +2.96]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,10.1)=0.83, p=0.3836
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction n.s. -- slopes parallel (no differential learning rate) (p=0.1941, slope diff=+1.18)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 15.18 13.424 17.167
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(134)= 1.74 F(1)= 3.015 p=0.08481
|
||||
day (learning) t(134)= 16.74 F(1)= 280.201 p=1.213e-34
|
||||
stim (main, window start) t(134)= 1.48 F(1)= 2.198 p=0.1405
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(134)= 1.74 F(1)= 3.015 p=0.08481 p=0.08489 (df=129)
|
||||
day (learning) t(134)= 16.74 F(1)=280.201 p=1.213e-34 p=2.161e-34 (df=131)
|
||||
stim (main, window start) t(134)= 1.48 F(1)= 2.198 p=0.1405 p=0.1519 (df=23)
|
||||
interaction 95% CI: [-0.18, +2.79]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,25.3)=2.32, p=0.1403
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction n.s. -- slopes parallel (no differential learning rate) (p=0.08481, slope diff=+1.31)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 12.477 10.33 15.071
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(61)= 3.15 F(1)= 9.909 p=0.002545
|
||||
day (learning) t(61)= 8.14 F(1)= 66.293 p=2.506e-11
|
||||
stim (main, window start) t(61)= 0.15 F(1)= 0.022 p=0.8814
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(61)= 3.15 F(1)= 9.909 p=0.002545 p=0.002679 (df=54)
|
||||
day (learning) t(61)= 8.14 F(1)= 66.293 p=2.506e-11 p=5.765e-11 (df=54)
|
||||
stim (main, window start) t(61)= 0.15 F(1)= 0.022 p=0.8814 p=0.8822 (df=24)
|
||||
interaction 95% CI: [+2.34, +10.47]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,10.5)=5.80, p=0.03561
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction SIGNIFICANT positive -- treatment improves FASTER (benefit accumulates) (p=0.002545, slope diff=+6.40)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 10.142 8.1466 12.627
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(46)= -0.73 F(1)= 0.535 p=0.4682
|
||||
day (learning) t(46)= 4.77 F(1)= 22.779 p=1.877e-05
|
||||
stim (main, window start) t(46)= 2.54 F(1)= 6.429 p=0.01469
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(46)= -0.73 F(1)= 0.535 p=0.4682 p=0.4687 (df=40)
|
||||
day (learning) t(46)= 4.77 F(1)= 22.779 p=1.877e-05 p=2.436e-05 (df=40)
|
||||
stim (main, window start) t(46)= 2.54 F(1)= 6.429 p=0.01469 p=0.02198 (df=16)
|
||||
interaction 95% CI: [-6.07, +2.84]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,10.0)=0.41, p=0.5344
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction n.s. -- slopes parallel (no differential learning rate) (p=0.4682, slope diff=-1.62)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 11.525 9.6827 13.718
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(69)= 0.63 F(1)= 0.397 p=0.5308
|
||||
day (learning) t(69)= 4.26 F(1)= 18.109 p=6.446e-05
|
||||
stim (main, window start) t(69)= 2.21 F(1)= 4.886 p=0.03039
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(69)= 0.63 F(1)= 0.397 p=0.5308 p=0.5309 (df=65)
|
||||
day (learning) t(69)= 4.26 F(1)= 18.109 p=6.446e-05 p=6.931e-05 (df=64)
|
||||
stim (main, window start) t(69)= 2.21 F(1)= 4.886 p=0.03039 p=0.0412 (df=17)
|
||||
interaction 95% CI: [-1.89, +3.64]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,8.5)=0.16, p=0.6966
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction n.s. -- slopes parallel (no differential learning rate) (p=0.5308, slope diff=+0.87)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 4.4892 4.0771 4.9429
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(227)= 2.66 F(1)= 7.088 p=0.008315
|
||||
day (learning) t(227)= 8.94 F(1)= 79.838 p=1.43e-16
|
||||
stim (main, window start) t(227)= 0.92 F(1)= 0.839 p=0.3606
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(227)= 2.66 F(1)= 7.088 p=0.008315 p=0.008365 (df=208)
|
||||
day (learning) t(227)= 8.94 F(1)= 79.838 p=1.43e-16 p=2.16e-16 (df=209)
|
||||
stim (main, window start) t(227)= 0.92 F(1)= 0.839 p=0.3606 p=0.3656 (df=37)
|
||||
interaction 95% CI: [+0.15, +0.97]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,24.0)=3.01, p=0.09541
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction SIGNIFICANT positive -- treatment improves FASTER (benefit accumulates) (p=0.008315, slope diff=+0.56)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 11.956 10.063 14.205
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(68)= 1.83 F(1)= 3.336 p=0.07218
|
||||
day (learning) t(68)= 10.55 F(1)= 111.222 p=5.943e-16
|
||||
stim (main, window start) t(68)= 0.37 F(1)= 0.134 p=0.7159
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(68)= 1.83 F(1)= 3.336 p=0.07218 p=0.07218 (df=68)
|
||||
day (learning) t(68)= 10.55 F(1)=111.222 p=5.943e-16 p=4.533e-16 (df=70)
|
||||
stim (main, window start) t(68)= 0.37 F(1)= 0.134 p=0.7159 p=0.7187 (df=19)
|
||||
interaction 95% CI: [-0.16, +3.62]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,20.5)=2.56, p=0.1246
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction n.s. -- slopes parallel (no differential learning rate) (p=0.07218, slope diff=+1.73)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 14.12 12.139 16.425
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(80)= 2.01 F(1)= 4.031 p=0.04804
|
||||
day (learning) t(80)= 9.45 F(1)= 89.224 p=1.171e-14
|
||||
stim (main, window start) t(80)= 0.63 F(1)= 0.401 p=0.5285
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(80)= 2.01 F(1)= 4.031 p=0.04804 p=0.04788 (df=84)
|
||||
day (learning) t(80)= 9.45 F(1)= 89.224 p=1.171e-14 p=7.518e-15 (df=84)
|
||||
stim (main, window start) t(80)= 0.63 F(1)= 0.401 p=0.5285 p=0.5284 (df=84)
|
||||
interaction 95% CI: [+0.02, +3.39]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,20.2)=2.92, p=0.1029
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction SIGNIFICANT positive -- treatment improves FASTER (benefit accumulates) (p=0.04804, slope diff=+1.70)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 9.9638 7.8829 12.594
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(38)= 2.92 F(1)= 8.511 p=0.005897
|
||||
day (learning) t(38)= 7.17 F(1)= 51.382 p=1.458e-08
|
||||
stim (main, window start) t(38)= -0.73 F(1)= 0.534 p=0.4696
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(38)= 2.92 F(1)= 8.511 p=0.005897 p=0.006128 (df=35)
|
||||
day (learning) t(38)= 7.17 F(1)= 51.382 p=1.458e-08 p=2.321e-08 (df=35)
|
||||
stim (main, window start) t(38)= -0.73 F(1)= 0.534 p=0.4696 p=0.4735 (df=20)
|
||||
interaction 95% CI: [+1.62, +8.99]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,7.0)=3.94, p=0.08763
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction SIGNIFICANT positive -- treatment improves FASTER (benefit accumulates) (p=0.005897, slope diff=+5.31)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 8.1802 6.1646 10.855
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(26)= 1.08 F(1)= 1.172 p=0.289
|
||||
day (learning) t(26)= 1.31 F(1)= 1.722 p=0.201
|
||||
stim (main, window start) t(26)= 1.61 F(1)= 2.596 p=0.1192
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(26)= 1.08 F(1)= 1.172 p=0.289 p=0.2898 (df=24)
|
||||
day (learning) t(26)= 1.31 F(1)= 1.722 p=0.201 p=0.2019 (df=24)
|
||||
stim (main, window start) t(26)= 1.61 F(1)= 2.596 p=0.1192 p=0.1297 (df=14)
|
||||
interaction 95% CI: [-2.18, +7.03]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,6.0)=0.90, p=0.3784
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction n.s. -- slopes parallel (no differential learning rate) (p=0.289, slope diff=+2.42)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 7.3669 5.8525 9.2731
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(38)= 2.32 F(1)= 5.379 p=0.02585
|
||||
day (learning) t(38)= 1.70 F(1)= 2.885 p=0.09761
|
||||
stim (main, window start) t(38)= 1.64 F(1)= 2.685 p=0.1096
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(38)= 2.32 F(1)= 5.379 p=0.02585 p=0.02591 (df=38)
|
||||
day (learning) t(38)= 1.70 F(1)= 2.885 p=0.09761 p=0.09766 (df=38)
|
||||
stim (main, window start) t(38)= 1.64 F(1)= 2.685 p=0.1096 p=0.1304 (df=11)
|
||||
interaction 95% CI: [+0.35, +5.17]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,21.2)=4.96, p=0.03697
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction SIGNIFICANT positive -- treatment improves FASTER (benefit accumulates) (p=0.02585, slope diff=+2.76)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 12.508 10.37 15.086
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(57)= 1.49 F(1)= 2.208 p=0.1428
|
||||
day (learning) t(57)= 10.08 F(1)= 101.556 p=2.832e-14
|
||||
stim (main, window start) t(57)= 0.68 F(1)= 0.466 p=0.4974
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(57)= 1.49 F(1)= 2.208 p=0.1428 p=0.1428 (df=57)
|
||||
day (learning) t(57)= 10.08 F(1)=101.556 p=2.832e-14 p=1.931e-14 (df=59)
|
||||
stim (main, window start) t(57)= 0.68 F(1)= 0.466 p=0.4974 p=0.5037 (df=17)
|
||||
interaction 95% CI: [-0.54, +3.66]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,13.0)=1.46, p=0.2479
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction n.s. -- slopes parallel (no differential learning rate) (p=0.1428, slope diff=+1.56)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 14.676 12.436 17.32
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(66)= 1.65 F(1)= 2.721 p=0.1038
|
||||
day (learning) t(66)= 9.09 F(1)= 82.593 p=3.035e-13
|
||||
stim (main, window start) t(66)= 0.95 F(1)= 0.910 p=0.3436
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(66)= 1.65 F(1)= 2.721 p=0.1038 p=0.1035 (df=70)
|
||||
day (learning) t(66)= 9.09 F(1)= 82.593 p=3.035e-13 p=1.823e-13 (df=70)
|
||||
stim (main, window start) t(66)= 0.95 F(1)= 0.910 p=0.3436 p=0.3434 (df=70)
|
||||
interaction 95% CI: [-0.33, +3.42]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,12.8)=1.64, p=0.2227
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction n.s. -- slopes parallel (no differential learning rate) (p=0.1038, slope diff=+1.55)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 10.703 8.3104 13.785
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(32)= 2.57 F(1)= 6.588 p=0.01515
|
||||
day (learning) t(32)= 6.67 F(1)= 44.528 p=1.571e-07
|
||||
stim (main, window start) t(32)= -0.40 F(1)= 0.163 p=0.6888
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(32)= 2.57 F(1)= 6.588 p=0.01515 p=0.0155 (df=30)
|
||||
day (learning) t(32)= 6.67 F(1)= 44.528 p=1.571e-07 p=2.162e-07 (df=30)
|
||||
stim (main, window start) t(32)= -0.40 F(1)= 0.163 p=0.6888 p=0.6906 (df=19)
|
||||
interaction 95% CI: [+1.11, +9.62]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,6.0)=3.02, p=0.1331
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction SIGNIFICANT positive -- treatment improves FASTER (benefit accumulates) (p=0.01515, slope diff=+5.36)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'Res Std'} 8.6289 6.3295 11.764
|
||||
|
||||
|
||||
effect t (df) F (df1) p
|
||||
------------------------------------------------------------------
|
||||
stim x day (interaction) t(21)= 0.71 F(1)= 0.503 p=0.486
|
||||
day (learning) t(21)= 1.24 F(1)= 1.547 p=0.2273
|
||||
stim (main, window start) t(21)= 1.73 F(1)= 3.008 p=0.09752
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(21)= 0.71 F(1)= 0.503 p=0.486 p=0.4864 (df=20)
|
||||
day (learning) t(21)= 1.24 F(1)= 1.547 p=0.2273 p=0.2279 (df=20)
|
||||
stim (main, window start) t(21)= 1.73 F(1)= 3.008 p=0.09752 p=0.1098 (df=11)
|
||||
interaction 95% CI: [-3.41, +6.95]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,5.0)=0.40, p=0.5549
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
INTERPRETATION: stim x day interaction n.s. -- slopes parallel (no differential learning rate) (p=0.486, slope diff=+1.77)
|
||||
Paper (N=24): interaction t(227)=2.68, F(1)=7.12, p=0.008.
|
||||
|
||||
@@ -21,11 +21,27 @@ 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);
|
||||
As = anova(m, 'DFMethod', 'satterthwaite'); % Satterthwaite denominator DF
|
||||
|
||||
% Honest test: refit with a per-animal random SLOPE so the interaction DF
|
||||
% collapses toward the animal count (guarded -- may not converge in short windows).
|
||||
rsP = NaN; rsDf = NaN; rsF = NaN; rsOk = false;
|
||||
wst = warning('off', 'all');
|
||||
try
|
||||
mr = fitlme(tbl, 'behavior ~ stim + day + stim:day + (day|rat)');
|
||||
Ar = anova(mr, 'DFMethod', 'satterthwaite');
|
||||
ri = strcmp(Ar.Term, 'day:stim');
|
||||
rsF = Ar.FStat(ri); rsDf = Ar.DF2(ri); rsP = Ar.pValue(ri); rsOk = true;
|
||||
catch
|
||||
end
|
||||
warning(wst);
|
||||
|
||||
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)));
|
||||
gs = @(t) find(strcmp(As.Term, t), 1);
|
||||
row = @(nm, t) sprintf('%-26s t(%d)=%6.2f F(%d)=%7.3f p=%.4g p=%.4g (df=%.0f)\n', nm, ...
|
||||
C.DF(gi(t)), C.tStat(gi(t)), A.DF1(ga(t)), A.FStat(ga(t)), C.pValue(gi(t)), ...
|
||||
As.pValue(gs(t)), As.DF2(gs(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));
|
||||
@@ -54,11 +70,18 @@ s = [s sprintf('control (stim=0): %s\n', strjoin(cellstr(unique(D.group(D.stim
|
||||
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 sprintf('%-26s %-18s %-12s %s\n%s\n', 'effect', 't(df) / F(df1)', 'p (resid)', 'Satterthwaite: p (df)', repmat('-', 1, 76))];
|
||||
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))];
|
||||
if rsOk
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): interaction F(1,%.1f)=%.2f, p=%.4g\n', rsDf, rsF, rsP)];
|
||||
else
|
||||
s = [s sprintf('HONEST LME (per-animal random slope, day|rat): did not converge for this window.\n')];
|
||||
end
|
||||
s = [s sprintf([' (Satterthwaite DF ~= residual on this random-intercept model; the random-slope\n' ...
|
||||
' model above is the honest learning-rate test -- DF collapses toward the animal count.)\n'])];
|
||||
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')];
|
||||
|
||||
@@ -70,5 +93,6 @@ 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, ...
|
||||
'interPsatt', As.pValue(gs('day:stim')), 'interPrs', rsP, ...
|
||||
'stimP', C.pValue(gi('stim')), 'dayP', C.pValue(gi('day')), ...
|
||||
'covEqual', abs(maxT - maxC) <= 2);
|
||||
|
||||
@@ -55,11 +55,14 @@ Group: Error
|
||||
{'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
|
||||
effect t(df) / F(df1) p (resid) Satterthwaite: p (df)
|
||||
----------------------------------------------------------------------------
|
||||
stim x day (interaction) t(30)= 1.71 F(1)= 2.933 p=0.0971 p=0.09701 (df=30)
|
||||
day (learning) t(30)= 1.61 F(1)= 2.598 p=0.1175 p=0.1174 (df=30)
|
||||
stim (main, window start) t(30)= 1.69 F(1)= 2.856 p=0.1014 p=0.1269 (df=9)
|
||||
interaction 95% CI: [-0.44, +4.97]
|
||||
HONEST LME (per-animal random slope, day|rat): interaction F(1,13.9)=2.48, p=0.1382
|
||||
(Satterthwaite DF ~= residual on this random-intercept model; the random-slope
|
||||
model above is the honest learning-rate test -- DF collapses toward the animal count.)
|
||||
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