Repeated measures ANOVA with two variables

65 views (last 30 days)
Hello,
I'm trying to carry out a repeated-measures ANOVA for the following data:
Normally, I would get the significance value for the two main factors (i.e. Crowding and Beta) as well as the significance value for the interaction (Crowding*Beta). Also, I would like to run the post-hoc analyses. I can't find the proper code to run this simple analysis, would very much appreciate any help.
-Mikel
  2 Comments
Scott MacKenzie
Scott MacKenzie on 26 Jul 2021
Edited: Scott MacKenzie on 26 Jul 2021
It would help if you post the actual data, rather than an image of the data.

Sign in to comment.

Accepted Answer

Scott MacKenzie
Scott MacKenzie on 27 Jul 2021
Edited: Scott MacKenzie on 27 Jul 2021
Here's what I put together. None of the effects are statistically significant. See below. Were the data in the Value column just randomly generated? Fair enough, since you're mostly just trying get off and running with ranova.
BTW, I'm including a function at the end to re-work the table generated by ranova into a more conventional format. If you want to compare my table to the one generated by ranova, just remove the semicolon at the end of the ranova line.
% read data (sorted, 2x2 within-subjects design with 17 participants)
f = 'https://www.mathworks.com/matlabcentral/answers/uploaded_files/696039/Q2.xls';
T = readtable(f);
% ingore extra data at end
T = T(1:2*2*17,:);
% organize the data in a 17x4 matrix (1 row per participant)
dv = array2table(reshape(T.Value, 17, [])); % dependent variable is 'Value'
% codes for column names: gr=grouped, ug=ungrouped, b1=beta1, b2=beta2
dv.Properties.VariableNames = {'grb1', 'grb2', 'ugb1', 'ugb2' };
% create the within-subjects design
withinDesign = table([1 1 2 2]',[1 2 1 2]','VariableNames',{'Crowding','Beta'});
withinDesign.Crowding = categorical(withinDesign.Crowding);
withinDesign.Beta = categorical(withinDesign.Beta);
% create repeated measures model
rm = fitrm(dv, 'grb1-ugb2 ~ 1', 'WithinDesign', withinDesign);
% perform anova (remove semicolon to view table generated by ranova)
AT = ranova(rm, 'WithinModel', 'Crowding*Beta');
% output an improved version of the anova table
disp(anovaTable(AT, 'Value'));
ANOVA table for Value =================================================================================== Effect df SS MS F p ----------------------------------------------------------------------------------- Participant 16 0.992 0.062 Crowding 1 0.064 0.064 0.607 0.4472 Participant(Crowding) 16 1.679 0.105 Beta 1 0.281 0.281 3.295 0.0883 Participant(Beta) 16 1.364 0.085 Crowding:Beta 1 0.000 0.000 0.005 0.9473 Participant(Crowding:Beta) 16 1.306 0.082 ===================================================================================
% -----------------------------------------------------------------------------------
% Scott's function to create a standard-looking ANOVA table from the
% terrible anova table created by the ranova function.
function [s] = anovaTable(AT, dvName)
c = table2cell(AT);
% remove erroneous entries in F and p columns
for i=1:size(c,1)
if c{i,4} == 1
c(i,4) = {''};
end
if c{i,5} == .5
c(i,5) = {''};
end
end
% use conventional labels in Effect column
effect = AT.Properties.RowNames;
for i=1:length(effect)
tmp = effect{i};
tmp = erase(tmp, '(Intercept):');
tmp = strrep(tmp, 'Error', 'Participant');
effect(i) = {tmp};
end
% determine the required width of the table
fieldWidth1 = max(cellfun('length', effect)); % width of Effect column
fieldWidth2 = 57; % field needed for df, SS, MS, F, and p columns
barDouble = sprintf('%s\n', repmat('=', 1, fieldWidth1 + fieldWidth2));
barSingle = sprintf('%s\n', repmat('-', 1, fieldWidth1 + fieldWidth2));
% re-organize the data
c = c(2:end,[2 1 3 4 5]);
c = [num2cell(repmat(fieldWidth1, size(c,1), 1)), effect(2:end), c]';
% create the ANOVA table
s = sprintf('ANOVA table for %s\n', dvName);
s = [s barDouble];
s = [s sprintf('%-*s %4s %10s %14s %10s %10s\n', fieldWidth1, 'Effect', 'df', 'SS', 'MS', 'F', 'p')];
s = [s barSingle];
s = [s, sprintf('%-*s %4d %14.3f %14.3f %10.3f %10.4f\n', c{:})];
s = [s, barDouble];
end
  3 Comments
Scott MacKenzie
Scott MacKenzie on 27 Jul 2021
@Mikel Jimenez, you're welcome. Glad to help.
Yes, multcompare is your tool for post hoc pairwise testing. Since your factors only have two levels each, such a test isn't necessary. If you want to do the comparisons between your 2x2 = 4 conditions, then you need to define a new/fake variable for the 4 conditions. The following code can be added to my answer for this purpose. Spioler alert: None of the pairs differ significantly.
% post hoc comparisons between the 4 columns (2 factors merged)
withinDesign2 = table([1 2 3 4]', 'VariableNames', {'IV2'});
withinDesign2.IV2 = categorical(withinDesign2.IV2);
rm2 = fitrm(dv, 'grb1-ugb2 ~ 1', 'WithinDesign', withinDesign2);
multcompare(rm2, 'IV2')
Mikel  Jimenez
Mikel Jimenez on 27 Jul 2021
Hi Scott,
If the interaction would have been significant, I think I would've need to look to the pairwise tests. Anyway, thank you very very much again, the code with the multcompare seems to work fine too!
Best,
Mikel

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!