Dummy variable coding in mixed models (LME)
Show older comments
Hi all,
I've been a little perplexed by the different ways to code dummy variables when fitting a linear mixed model (using fitlme). Specifically I have a model with two categorical fixed factors. I'd like to do contrasts between the different levels of each factor. Now several online sources tell me I should use 'effects' coding for this, but it isn't clear to me why this is, nor is it clear to me how I should code my contrast matrix when using 'effects' coding rather than reference coding.
For example, if I have a model with an intercept and one categorical fixed factor with three levels, such that:
T = table(y,var1); % y is my response variable, var1 a categorical variable with three levels
formula = 'y ~ var1';
m1 = fitlme(T,formula,'DummyVarCoding', 'reference');
me1 = fitlme(T,formula,'DummyVarCoding', 'effects');
Now I'd like to test whether there's a difference between the first and second categories. In the case of the m1 (reference coding) and me1 (effects coding) I would do this as follows:
[p,F,df1,df2] = coefTest(m1,[0 1 0]); % coefTest(lme,H)
[pe,Fe,df1e,df2e] = coefTest(me1,[1 1 0]);
This gives me very different results even though in both cases multiplying each contrast matrix with the associated fixed effects matrix gives me the same value (according to the documentation for coefTest: "It tests the null hypothesis that H0: Hβ = 0, where β is the fixed-effects vector."
When I try both options with some simulated data, where the first two levels of the fixed factor differ significantly, I only find this significant difference when using reference coding. Any insight would be greatly appreciated.
Here's the code for some simulated data:
d1 = zeros(100,1)+randn(100,1);
d2 = ones(100,1)+randn(100,1);
d3 = ones(100,1).*2+randn(100,1);
d = [d1;d2;d3];
cov1 = [zeros(100,1);ones(100,1);ones(100,1).*2];
T = table(d,categorical(cov1),'VariableNames',{'d','cov1'});
f = 'd~cov1';
m1 = fitlme(T,f);
me1 = fitlme(T,f,'DummyVarCoding','effects');
[p,F,df1,df2] = coefTest(m1,[0 1 0]); % coefTest(lme,H)
[pe,Fe,df1e,df2e] = coefTest(me1,[1 1 0]);
Accepted Answer
More Answers (3)
osman
on 19 Aug 2025
0 votes
Hi,
I understand what you said above. I might missing something but the example that I see when I type doc coeftest in MATLAB is below. Here they say the difference between the evening and morning shifts is found by pVal = coefTest(lme,[0 1 -1]) but it should be like yours pVal = coefTest(lme,[0 1 0]). Am I wrong?
load('shift.mat')
shift.Shift = nominal(shift.Shift);
shift.Operator = nominal(shift.Operator);
lme = fitlme(shift,'QCDev ~ Shift + (1|Operator)') %not effects coding, reference coding
%the output
%Fixed effects coefficients (95% CIs):
% Name Estimate SE tStat DF pValue
% {'(Intercept)' } 3.1196 0.88681 3.5178 12 0.0042407
% {'Shift_Morning'} -0.3868 0.48344 -0.80009 12 0.43921
% {'Shift_Night' } 1.9856 0.48344 4.1072 12 0.0014535
%Test if there is any difference between the evening and morning shifts.
pVal = coefTest(lme,[0 1 -1])
1 Comment
osman
on 21 Aug 2025
0 votes
Thanks, yes. Here is what you said and they gave the same p val.
clear all
load('shift.mat')
lmeR = fitlme(shift,'QCDev ~ Shift + (1|Operator)')
lmeE = fitlme(shift,'QCDev ~ Shift + (1|Operator)','DummyVarCoding','effects')
% % Test if there is any difference between the evening and morning shifts.
pVal_ref = coefTest(lmeR,[0 1 0])
pVal_E = coefTest(lmeE,[0 1 -1])
%the output
%pVal_ref =
% 0.4392
%pVal_E =
% 0.4392
Here is the link they test the reference coded model with the wrong coefTest H matrix (the one for effects coding) 0 1 -1.
https://www.mathworks.com/help/stats/linearmixedmodel.coeftest.html
Basically they used the H matrix of effects coded model in the ref. coded model. I guess they made this mistake because in the link below they used the same model with effects coding but forgot to do the same way for writing the help section of coeftest.
Do you agree?
Categories
Find more on Analysis of Variance and Covariance in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!