3dANOVA3 for a 3-way, within-subject?

AFNI version info (afni -ver): 23.3.13

Hi! I was wondering... Would it be correct to estimate a 3-way within-subject ANOVA?
Say I have 30 subjects that go through the same 3 conditions, 2 levels each (2x2x2). Something like all participants viewing objects that are:

abstract-small-colored (1-1-1)
abstract-small-grey (1-1-2)
abstract-big-colored (1-2-1)
abstract-big-grey (1-2-2)
concrete-small-colored (2-1-1)
concrete-small-grey (2-1-2)
concrete-big-colored (2-2-1)
concrete-big-grey (2-2-2)

Although this is a made-up example, I know that conceptually, it would make sense to test these 3 factors and their interactions, but is it statistically sound to run this type of ANOVA using 3dANOVA3? (Instead of running 2-3 versions with the collapsed conditions). All examples I see are max. 2-way + a between-subject factor.

Of course I can run:

3dANOVA3 -type 1                                                                     \
    -alevels 2                                                                       \
    -blevels 2                                                                       \
    -clevels 2                                                                       \
    -dset  1  1  1 "sub-00.results/rall_func+tlrc.HEAD[cond_1-1-1#0_Coef]" \
    -dset  1  1  2 "sub-00.results/rall_func+tlrc.HEAD[cond_1-1-2#0_Coef]"  \
    -dset  1  2  1 "sub-00.results/rall_func+tlrc.HEAD[cond_1-2-1#0_Coef]" \
 ...
    -dset  2  1  2 "sub-29.results/rall_func+tlrc.HEAD[cond_2-1-2#0_Coef]"  \
    -dset  2  2  2 "sub-29.results/rall_func+tlrc.HEAD[cond_2-2-2#0_Coef]" \
 ...
[contrasts and options]

...but I'm not sure if 3dANOVA3 is meant to run this. Also, gen_group_command.py is not meant to generate this kind of analyses. If it is sound, it would be good to have the option to avoid the tedious scripting.

Thanks in advance!

The 3dANOVA3 -type 4 program is suitable for conducting a two-way within-subject ANOVA but does not support three-way within-subject ANOVA. If you need to analyze a 2 \times 2 \times 2 within-subject ANOVA, you can utilize either 3dMVM or 3dLMEr . For guidance on model specification with 3dLMEr , refer to this blog post.

Gang Chen

Dear Gang Chen,

Thank you for your advice.

I've been delving into 3dLMEr and 3dMVM, and decided to go with 3dLMEr because this way I can run the 2x2x2 while controlling for a quantitative variable (RT).

Here is what I've been trying after checking the post you shared:

3dLMEr -prefix group_results/lme/lme_res -jobs 12                                                                                                                   \
 -model 'concr*fam*freq*RT+(1+RT|Subj)+(1+RT|concr:Subj)+(1+RT|fam:Subj)+(1+RT|freq:Subj)+(1+RT|concr:fam:Subj)+(1+RT|concr:freq:Subj)+(1+RT|fam:freq:Subj)'        \
 -SS_type 3                                                                                                                                                         \
 -glfCode abs_famxfreq 'concr : 1*abs fam : 1*lfam -1*hfam freq : 1*low -1*hi'                                                                                      \
 -glfCode con_famxfreq 'concr : 1*con fam : 1*lfam -1*hfam freq : 1*low -1*hi'                                                                                      \
 -gltCode abs-con 'concr : 1*abs -1*con fam : 1*lfam & 1*hfam freq : 1*low & 1*hi'                                                                                  \
 -gltCode lfam-hfam 'concr : 1*abs & 1*con fam : 1*lfam -1*hfam freq : 1*low & 1*hi'                                                                                \
 -gltCode low-hi 'concr : 1*abs & 1*con fam : 1*lfam & 1*hfam freq : 1*low -1*hi'                                                                                   \
 -data_table @anova_table.txt

However, I have a couple of doubts/issues:

  1. Is this a correct way to estimate what I wanted?

  2. When I run this (or other different models) I keep getting the error:

** Error: 
   Expecting 1 parameters for option "-model".
   Have 3 parameter(s) in string "concr*fam*freq*RT+(1+RT|Subj)+(1+RT|concr:Subj)+(1+RT|fam:Subj)+(1+RT|freq:Subj)+(1+RT|concr:fam:Subj)+(1+RT|concr:freq:Subj)+(1+RT|fam:freq:Subj) -SS_type 3" instead.
   NOTE that -SS_type in bad option above is not a recognized option.

** Error: 
   Error parsing arguments. See 3dLMEr -help for details.

Also checked the quotes and tried all types of quotes, but made no difference.
I run it as a .sh script and also by copying in the terminal, but it makes no difference.
I checked the script with

file_tool -test -infile [script]

And it gave me no errors.

I'm a bit puzzled, and I'm sure I'm missing something reeaaally basic... Any idea?

Thank you!!

  1. Is this a correct way to estimate what I wanted?

Including RT as a covariate can be tricky. I suggest the following:

  • It might be necessary to center RT within each of 8 combinations. Check the discussion here.

  • It would be prudent to run the analysis without RT and compare the results.

When I run this (or other different models) I keep getting the error

What is your AFNI version (afni -ver)? Update your AFNI and try the script again.

>  -glfCode abs_famxfreq 'concr : 1*abs fam : 1*lfam -1*hfam freq : 1*low -1*hi'                                                                                      \
>  -glfCode con_famxfreq 'concr : 1*con fam : 1*lfam -1*hfam freq : 1*low -1*hi'                                                                                      \

These two tests have one degree of freedom, so it would be more straightforward to use -gltCode (instead of -glfCode) to obtain the sign of the comparisons.

  -gltCode abs-con 'concr : 1*abs -1*con fam : 1*lfam & 1*hfam freq : 1*low & 1*hi'                                                                                  \
-gltCode lfam-hfam 'concr : 1*abs & 1*con fam : 1*lfam -1*hfam freq : 1*low & 1*hi'                                                                                \
-gltCode low-hi 'concr : 1*abs & 1*con fam : 1*lfam & 1*hfam freq : 1*low -1*hi'                                                                                   \

These three lines lack clarity and 3dLMEr would not accept them. Could you provide more details regarding your intended comparisons?

Gang Chen

Thank you for your reply.

Ok perfect. I will do as you say for the RT.

What is your AFNI version (afni -ver)? Update your AFNI and try the script again.

I was indeed running with an older version of AFNI, and some R packages where giving problems. After updating it the error disappeared.

These two tests have one degree of freedom, so it would be more straightforward to use -gltCode (instead of -glfCode) to obtain the sign of the comparisons.

  -glfCode abs_famxfreq 'concr : 1*abs fam : 1*lfam -1*hfam freq : 1*low -1*hi'                                                                                      \
-glfCode con_famxfreq 'concr : 1*con fam : 1*lfam -1*hfam freq : 1*low -1*hi'                                                                                      \

My intention was to check main effects and interaction of B (fam) and C (freq), while fixing A(concr) at each of the 2 levels. How would that be expressed? I think I misread the 3dLMEr -help then?

These three lines lack clarity and 3dLMEr would not accept them. Could you provide more details regarding your intended comparisons?

-gltCode abs-con 'concr : 1*abs -1*con fam : 1*lfam & 1*hfam freq : 1*low & 1*hi'                                                                                  \
-gltCode lfam-hfam 'concr : 1*abs & 1*con fam : 1*lfam -1*hfam freq : 1*low & 1*hi'                                                                                \
-gltCode low-hi 'concr : 1*abs & 1*con fam : 1*lfam & 1*hfam freq : 1*low -1*hi'                                                                                   \

Here I just wanted to check simple effects in A, B and C separately. This is, level 1 of A vs level 2 of A, collapsing the levels of B and C. Same for the other factors.

I found a new issue though... It seems my dataTable is not rectangular:

Error in if (len%%wd != 0) errex.AFNI(paste("The content under -dataTable is not rectangular!",  : 
  argument is of length zero

I checked and there are no bad characters, no spaces after backslash or whatsoever. I tried both by providing the file with @dataTable, and by copying it directly on the script, but I get the same. I also tried adding/removing the quotes for the brackets. The table looks like this:

Subj	RT	concr	fam	freq	InputFile	\
sub-00	0.8306	abs	lfam	low	sub-00.results/regress/rall_func+tlrc[abs_lfam_low#0_Coef]	\
sub-00	0.7518	abs	lfam	hi	sub-00.results/regress/rall_func+tlrc[abs_lfam_hi#0_Coef]	\
sub-00	0.7674	abs	hfam	low	sub-00.results/regress/rall_func+tlrc[abs_hfam_low#0_Coef]	\
sub-00	0.6828	abs	hfam	hi	sub-00.results/regress/rall_func+tlrc[abs_hfam_hi#0_Coef]	\
sub-00	0.8367	con	lfam	low	sub-00.results/regress/rall_func+tlrc[con_lfam_low#0_Coef]	\
sub-00	0.7632	con	lfam	hi	sub-00.results/regress/rall_func+tlrc[con_lfam_hi#0_Coef]	\
sub-00	0.736	con	hfam	low	sub-00.results/regress/rall_func+tlrc[con_hfam_low#0_Coef]	\
sub-00	0.6861	con	hfam	hi	sub-00.results/regress/rall_func+tlrc[con_hfam_hi#0_Coef]	\

...

sub-29	0.7152	abs	lfam	low	sub-29.results/regress/rall_func+tlrc[abs_lfam_low#0_Coef]	\
sub-29	0.6164	abs	lfam	hi	sub-29.results/regress/rall_func+tlrc[abs_lfam_hi#0_Coef]	\
sub-29	0.6045	abs	hfam	low	sub-29.results/regress/rall_func+tlrc[abs_hfam_low#0_Coef]	\
sub-29	0.5931	abs	hfam	hi	sub-29.results/regress/rall_func+tlrc[abs_hfam_hi#0_Coef]	\
sub-29	0.662	con	lfam	low	sub-29.results/regress/rall_func+tlrc[con_lfam_low#0_Coef]	\
sub-29	0.6076	con	lfam	hi	sub-29.results/regress/rall_func+tlrc[con_lfam_hi#0_Coef]	\
sub-29	0.6019	con	hfam	low	sub-29.results/regress/rall_func+tlrc[con_hfam_low#0_Coef]	\
sub-29	0.6088	con	hfam	hi	sub-29.results/regress/rall_func+tlrc[con_hfam_hi#0_Coef]	

-glfCode abs_famxfreq 'concr : 1*abs fam : 1*lfam -1*hfam freq : 1*low -1*hi'                                                                                      \
-glfCode con_famxfreq 'concr : 1*con fam : 1*lfam -1*hfam freq : 1*low -1*hi'                                                                                      \

My intention was to check main effects and interaction of B (fam) and C (freq), while fixing A(concr) at each of the 2 levels. How would that be expressed? I think I misread the 3dLMEr -help then?

For the main effects of B and C while fixing A(concr) at each of the 2 levels, add

-gltCode abs_fam 'concr : 1*abs fam : 1*lfam -1*hfam '                                                                                      \
-gltCode con_fam 'concr : 1*con fam : 1*lfam -1*hfam'                                                                                      \
-gltCode abs_freq 'concr : 1*abs freq : 1*low -1*hi'                                                                                      \
-gltCode con_freq 'concr : 1*con freq : 1*low -1*hi'                                                                                      \

For the interaction of B (fam) and C (freq) while fixing A(concr) at each of the 2 levels, add

-gltCode abs_famxfreq 'concr : 1*abs fam : 1*lfam -1*hfam freq : 1*low -1*hi'                                                                                      \
-gltCode con_famxfreq 'concr : 1*con fam : 1*lfam -1*hfam freq : 1*low -1*hi'                                                                                      \

Here I just wanted to check simple effects in A, B and C separately. This is, level 1 of A vs level 2 of A, collapsing the levels of B and C. Same for the other factors.

-gltCode abs-con 'concr : 1*abs -1*con fam : 1*lfam & 1*hfam freq : 1*low & 1*hi'                                                                                  \
-gltCode lfam-hfam 'concr : 1*abs & 1*con fam : 1*lfam -1*hfam freq : 1*low & 1*hi'                                                                                \
-gltCode low-hi 'concr : 1*abs & 1*con fam : 1*lfam & 1*hfam freq : 1*low -1*hi'                                                                                   \

Change your original specifications to:

-gltCode abs-con 'concr : 1*abs -1*con'   \
-gltCode lfam-hfam 'fam : 1*lfam -1*hfam' \
-gltCode low-hi 'freq : 1*low -1*hi'      \

It seems my dataTable is not rectangular

One possibility is that at least one line is missing one or more items (or having one or more extra items). @discoraj , could you provide some diagnosis help?

Gang Chen

For extra info:
I have checked the table upside down. I see no missing/extra values.
I also tried different separators (the table I shared earlier was separated by \t), and different file formats.

Regarding the centering of RT, is it possible to provide the 8 centering values (e.g. the mean of each condition)? Like this:

-qVars RT
-qVarCenters '0.745,0.66,0.642,0.588,0.712,0.656,0.632,0.604'

Or should I just replace the RTs with their Z values in the dataTable?

Cheers!

Regarding the centering of RT, is it possible to provide the 8 centering values (e.g. the mean of each condition)? ... Or should I just replace the RTs with their Z values in the dataTable?

3dLMEr currently lacks an inherent within-cell centering mechanism. To address this, you may need to manually center the RT values for each of the 8 combinations. This can be achieved using loops in a programming language. Then integrate the centered values back into the table.

It would be interesting to check the differences between with and without incorporating RT.

I have checked the table upside down. I see no missing/extra values.

If you share the script and table via email, I can take a close look.

Gang Chen

P. S.

Upon careful examination of the script, a subtle error has been identified. The line

-data_table @anova_table.txt

should be

-dataTable @anova_table.txt