Thanks, Mike.
I think I have a solution, but it involves running the descriptive
statistics from within ezANOVA_main. ezStats is simply computing
means and standard deviations until it runs into Fisher's Least
Significant Difference (FLSD), for which it needs an ANOVA table.
Because it's a separate function from ezANOVA, ezStats needs to run an
ANOVA in order to get that ANOVA table, and that's where my error is
turning up. By putting descriptive stats into ezANOVA, you don't need
to re-run the ANOVA because you've already got the table in the
output. Just grab the bits you need to compute FLSD and voila.
If we add an option for 'descriptives' in the ezANOVA function:
ezANOVA <-
function(
data
, dv
...
, return_aov = FALSE
, descriptives = FALSE
){
[also add "descriptives = descriptives" in the function for the
"to_return =" statement.]
and then copy and paste the descriptive statistics formulas from
ezStats into ezANOVA_main right before the last line
(return(to_return)):
[note that I have added a line defining this_ANOVA as to_return$ANOVA
and a line at the very end appending the descriptives to the to_return
list].
if(descriptives) {
if (!is.null(within) & !is.null(between)) {
if (!is.logical(diff) & length(within) > 1) {
warning("Mixed within-and-between-Ss effect requested;
FLSD is only appropriate for within-Ss comparisons (see warning in ?
ezStats or ?ezPlot).",
call. = FALSE)
}
}
this_ANOVA = to_return$ANOVA
vars = as.character(c(between, within))
temp = idata.frame(cbind(data, ezWID = data[, names(data) ==
as.character(wid)], dummy = rep(1, length(data[, 1]))))
N = ddply(temp, structure(as.list(c(.(dummy), between)),
class = "quoted"), function(x) {
to_return = length(unique(x$ezWID))
names(to_return) = "N"
return(to_return)
})
if (!all(N[, length(N)] == N[1, length(N)])) {
warning("Unbalanced groups. Mean N will be used in
computation of FLSD")
N = mean(N[, length(N)])
}
else {
N = N[1, length(N)]
}
DFd = this_ANOVA$DFd[length(this_ANOVA$DFd)]
MSd = this_ANOVA$SSd[length(this_ANOVA$SSd)]/DFd
Tcrit = qt(0.975, DFd)
CI = Tcrit * sqrt(MSd/N)
FLSD = sqrt(2) * CI
temp = idata.frame(cbind(data, ezDV = data[, names(data) ==
as.character(dv)]))
data <- ddply(temp, structure(as.list(c(between, within)),
class = "quoted"), function(x) {
N = length(x$ezDV)
Mean = mean(x$ezDV)
SD = sd(x$ezDV)
return(c(N = N, Mean = Mean, SD = SD))
})
data$FLSD = FLSD
to_return$descriptives = data
}
Here's a test. If I go back to my unbalanced dataset and run ezANOVA
with the new descriptives=TRUE option:
> GSu <- GoodSamaritan[-42,]
> GSu <- GSu[-41,]
> table(GSu$messag,GSu$time.pressure)
High Medium Low
Jobs 6 7 7
Samaritan 7 7 6
> ezANOVA(
data = GSu
, dv = .(helping)
, wid = .(subj)
, between = .(time.pressure,messag)
, type = 3
, descriptives = TRUE)
I get the following, which works fine:
Warning: You have removed one or more Ss from the analysis.
Refactoring "subj" for ANOVA.
Warning: Data is unbalanced (unequal N per group). Make sure you
specified a well-considered value for the type argument to ezANOVA().
$ANOVA
Effect DFn DFd F p p<.05 ges
2 time.pressure 2 34 4.4331805 0.01946073 * 0.20683727
3 messag 1 34 0.8547151 0.36173728 0.02452222
4 time.pressure:messag 2 34 0.9797785 0.38574290 0.05449336
$`Levene's Test for Homogeneity of Variance`
DFn DFd SSn SSd F p p<.05
1 5 34 4.07619 31.02381 0.8934459 0.4964538
$descriptives
time.pressure messag N Mean SD FLSD
1 High Jobs 6 0.3333333 0.8164966 1.442738
2 High Samaritan 7 1.0000000 0.8164966 1.442738
3 Medium Jobs 7 1.8571429 0.8997354 1.442738
4 Medium Samaritan 7 1.5714286 1.7182494 1.442738
5 Low Jobs 7 2.4285714 1.5118579 1.442738
6 Low Samaritan 6 3.5000000 1.6431677 1.442738
Warning message:
In ezANOVA_main(data = data, dv = dv, wid = wid, within = within, :
Unbalanced groups. Mean N will be used in computation of FLSD
It's not a good solution because I'm not sure why ezStats isn't
working, but it is a bit computationally simpler.
--Bill