2

It's very much my first time on here, so go easy! Honestly with the amount of time I have spent troubleshooting, I could have done each by hand, but I'm determined to make this work....

I want to run 71 different one way ANOVA's comparing the volume of 71 brain regions of interest (ROI) with experimental group (group). There are three groups: control (1), resilient (2) and susceptible (3).

my tibble dataframe looks like this:

> head(df)
# A tibble: 6 x 74
  ID    group whole_brain amygdala arbor_vitae auditory_cortex bed_nuclei
  <chr> <dbl>       <dbl>    <dbl>       <dbl>           <dbl>      <dbl>
1 01mc      1        495.     16.5        5.72            5.29       1.30
2 02mc      1        494.     16.8        5.95            5.29       1.30
3 6mc       1        491.     16.9        5.75            5.31       1.17
4 11mc      1        485.     16.5        5.70            5.04       1.31
5 14mc      1        491.     17.1        6.03            5.06       1.21
6 18mc      1        492.     16.5        6.07            5.12       1.23

I've written a for-loop through which I expect R to iterate through the name of the brain region (each column, excluding whole_brain), and then summarise an ANOVA table:

# One-Way ANOVA -----------------------------------------------------------

for(i in 4:ncol(df)){

  column <- names(df[i]) # to print each ROI at the top of each ANOVA summary

  avz <- aov(df[,i] ~ group, data = df) # Each ANOVA test iterating through each column of my dataframe

  result <- summary(avz) # summarize each ANOVA in a table

  print(column)
  print(result)
}

Yet I get this error message:

Error in model.frame.default(formula = df[, i] ~ group, data = df, drop.unused.levels = TRUE) : 
  invalid type (list) for variable 'df[, i]'

When I swap the first object (df[,i]) in the aov() to a name of one of the ROIs (for example amygdala), the output gives each iterative ROI column name, with the chosen ANOVA (amygdala ~ group, data=df) underneath. This tells me the for loop works, but how do I overcome the error message and get it to systematically compare group to each ROI?

Any help would be amazing, even to point out if this is a totally old method and there is something way easier out there to use!

Thank you so much :)

CouchPotato
  • 21
  • 1
  • 2
  • In the summary of the ANOVA do you want to keep all elements ? And what output do you you require from all ANOVAs? – e.matt Apr 08 '20 at 18:31
  • Bottom line, I’d like to know effect size (R squared), p-value and confidence intervals (not hugely necessary but would be nice) for all ROI comparisons to group. From the ones that are significant, I can then do post-hoc testing. – CouchPotato Apr 08 '20 at 21:05

1 Answers1

3

It looks like it isn't the for loop itself thats not working, it one of the dependant variables you are passing to the aov is a list and not numeric.

To identify which columns are lists you can: sapply(df,class) and look for variables that are lists and fix

df$badvariable < - unlist(df$badvariable)

If you want to update your for loop to only print significant ANOVA results we can use tidy from library(broom) to summarise and output in neat format.

for(i in 4:ncol(df))
{

column <- names(df[i])
#tidy will summarise and return neat format
avz <- broom::tidy(aov(df[,i] ~ group, data = df))

# Add this condition if you only want aov with P < 0.05 printed
if(avz$p.value[1] < 0.05) {

  print(column)
  print(avz)
 }
}
e.matt
  • 836
  • 1
  • 5
  • 12
  • this is cool! Instead of printing the output how could you capture the summaries in a dataframe (e.g. avz)? – Dustin Feb 23 '23 at 01:44