Patrick
Patrick

Reputation: 1227

Automatically performing multiple within-subject ANOVA in R

My data are following

 time   id  var1    var2    var3    var4    var5    var6
a   1   36.9    82.7    22.2    24.2    37.9    46.5
a   2   35.0    88.9    27.4    27.3    37.4    44.9
a   3   39.6    85.6    23.1    24.0    35.4    46.0
a   4   37.1    87.6    25.2    25.5    39.7    47.1
a   5   36.9    87.1    25.8    25.1    36.7    44.4
a   6   37.7    89.7    25.8    26.6    41.9    41.2
a   7   36.2    87.3    25.6    26.0    34.5    42.0
a   8   37.1    88.3    25.5    26.0    39.7    41.6
a   9   34.9    87.8    26.2    26.9    35.7    45.1
a   10  39.7    87.4    24.7    23.3    40.0    41.3
b   1   37.3    91.7    27.9    27.1    39.0    46.4
b   2   41.0    87.3    23.4    23.5    39.0    49.1
b   3   36.9    91.0    27.7    27.1    43.0    44.6
b   4   34.1    91.3    28.6    28.9    38.6    42.7
b   5   35.7    87.3    25.9    26.3    41.4    44.8
b   6   39.7    89.5    25.3    25.0    39.1    45.5
b   7   42.4    89.8    25.6    22.2    43.2    50.3
b   8   37.3    89.9    26.1    26.8    38.3    42.9
b   9   37.5    93.5    29.0    27.7    40.1    50.8
b   10  39.4    91.7    26.0    26.5    42.0    51.6
c   1   38.5    89.3    24.6    26.3    41.7    48.9
c   2   38.4    85.8    24.0    24.3    35.4    40.8
c   3   40.2    94.3    27.0    27.9    40.7    44.1
c   4   35.9    88.4    26.7    26.5    37.8    44.5
c   5   37.7    88.0    25.9    24.6    36.4    44.1
c   6   34.1    84.7    25.4    25.3    37.4    43.4
c   7   36.1    84.8    24.5    24.8    39.6    44.7
c   8   38.6    90.1    26.4    25.6    38.7    47.8
c   9   34.5    84.7    25.1    25.2    37.7    42.1
c   10  35.2    84.6    24.9    24.9    33.7    38.9

Time is the within-subject factor, and var1 to var6 are different outcome measures. I want to perform within-subject ANOVA for each outcome measure to examine its temporal changes. I am using ezANOVA function in ez package to do the analysis.

Since there are many many outcome variables (columns) in my real dataset (only six is described here for illustrative purpose), I wish to write a for loop so that multiple within-subject ANOVA tests can be performed automatically.

I am using the following code:

library(ez)
obj<-NULL
for(i in 1:6){
    obj[[i]] <- ezANOVA(data = data, 
                        dv = .(as.factor(colnames(data)[i+2])), 
                        wid = .(id), 
                        within = .(time), 
                        detailed = T, type = 3)
}

Unfortunately, I got the following error message:

Error in ezANOVA_main(data = data, dv = dv, wid = wid, within = within,  : 
  "as.factor(colnames(data)[i + 2])" is not a variable in the data frame provided.

When I put "var1" inside the bracket, the function worked well with the following code:

ezANOVA(data = data3, 
        dv = .(var1), 
        wid = .(id), 
        within = .(time), 
        detailed = T, type = 3)

I think that probably ezANOVA function accepts only the exact variable name inside .(). Functions are not allowed there.

May I know if there is a way to run multiple within-subject ANOVA tests simultaneously without having to manually input the name of each outcome measure into .()?

Or if we can do some modifications of the ezANOVA source code, which can be obtained by typing ezANOVA in R, so that function is allowed inside .().

Any solution is welcome!

Upvotes: 0

Views: 1136

Answers (1)

AntoniosK
AntoniosK

Reputation: 16121

Not very familiar with the ezANOVA package, but instead of modifying the package I'm just doing some more data manipulation using dplyr. Check this and let me know if it works for you, or if you want me to improve it. You get all results as a data frame.

library(dplyr)
library(ez)

dt = read.table(text=" time   id  var1    var2    var3    var4    var5    var6
                a   1   36.9    82.7    22.2    24.2    37.9    46.5
                a   2   35.0    88.9    27.4    27.3    37.4    44.9
                a   3   39.6    85.6    23.1    24.0    35.4    46.0
                a   4   37.1    87.6    25.2    25.5    39.7    47.1
                a   5   36.9    87.1    25.8    25.1    36.7    44.4
                a   6   37.7    89.7    25.8    26.6    41.9    41.2
                a   7   36.2    87.3    25.6    26.0    34.5    42.0
                a   8   37.1    88.3    25.5    26.0    39.7    41.6
                a   9   34.9    87.8    26.2    26.9    35.7    45.1
                a   10  39.7    87.4    24.7    23.3    40.0    41.3
                b   1   37.3    91.7    27.9    27.1    39.0    46.4
                b   2   41.0    87.3    23.4    23.5    39.0    49.1
                b   3   36.9    91.0    27.7    27.1    43.0    44.6
                b   4   34.1    91.3    28.6    28.9    38.6    42.7
                b   5   35.7    87.3    25.9    26.3    41.4    44.8
                b   6   39.7    89.5    25.3    25.0    39.1    45.5
                b   7   42.4    89.8    25.6    22.2    43.2    50.3
                b   8   37.3    89.9    26.1    26.8    38.3    42.9
                b   9   37.5    93.5    29.0    27.7    40.1    50.8
                b   10  39.4    91.7    26.0    26.5    42.0    51.6
                c   1   38.5    89.3    24.6    26.3    41.7    48.9
                c   2   38.4    85.8    24.0    24.3    35.4    40.8
                c   3   40.2    94.3    27.0    27.9    40.7    44.1
                c   4   35.9    88.4    26.7    26.5    37.8    44.5
                c   5   37.7    88.0    25.9    24.6    36.4    44.1
                c   6   34.1    84.7    25.4    25.3    37.4    43.4
                c   7   36.1    84.8    24.5    24.8    39.6    44.7
                c   8   38.6    90.1    26.4    25.6    38.7    47.8
                c   9   34.5    84.7    25.1    25.2    37.7    42.1
                c   10  35.2    84.6    24.9    24.9    33.7    38.9", header=T)

# create a vector of names of variables of interest
variables_of_interest = dt %>% select(matches("var")) %>% names()


dt_res =
data.frame(variables_of_interest,                         ## create a data frame with variable names as a column
           stringsAsFactors = F) %>%
  group_by(variables_of_interest) %>%                     ## for each variable of interest
  do({dt2 = dt[,c(.$variables_of_interest,"id","time")]   ## pick that variable along with id and time
      names(dt2)[1] = "var"                               ## rename that variable to "var" (to be used as a name within ezANOVA)
      res = ezANOVA(data = dt2,                           ## run ezANOVA
                    dv = .(var), 
                    wid = .(id), 
                    within = .(time), 
                    detailed = T, type = 3)
      data.frame(res)})                                   ## save results as a dataframe to be returned next to the variable name

I'd suggest you run the code step by step to see how it works. Try to manually check that results are correct. Let me know if you're happy with the output, or if you want any modifications.

Upvotes: 1

Related Questions