Use S3 methods for effect size functions
crsh opened this issue · 1 comments
crsh commented
Hi Erin,
building on our other discussion, here some thoughts on how to handle different output objects. I would suggest to define S3 methods to do this to avoid "having to write it 10 times". Currently, you suggest to do the following for every effect:
##run my analysis
aov_saved = summary(aov(mpg~cyl, data = mtcars))
##process through MOTE
eta_saved = eta.anova(aov_saved[[1]][["Df"]][1], aov_saved[[1]][["Df"]][2], aov_saved[[1]][["F value"]][1], a = .05)
I would suggest the following:
# Define S3 generic
eta_anova <- function(x, ...) {
UseMethod("eta_anova", x)
}
# Define default method for users who want to pass statistics (e.g., from publications)
eta_anova.default <- function (x, dfm, dfe, a = .05) {
eta <- (dfm * x) / (dfm * x + dfe)
ncpboth <- conf.limits.ncf(x, df.1 = dfm, df.2 = dfe, conf.level = (1 - a))
elow <- ncpboth$Lower.Limit / (ncpboth$Lower.Limit + dfm + dfe + 1)
ehigh <- ncpboth$Upper.Limit / (ncpboth$Upper.Limit + dfm + dfe + 1)
p <- pf(x, dfm, dfe, lower.tail = F)
output <- data.frame(es = eta,
es_ll = elow,
es_ul = ehigh,
Fvalue = x,
dfm = dfm,
dfe = dfe)
attr(output, "model") <- c(F = x, dfm = dfm, dfe = dfe)
class(output) <- c("mote_anova", class(output))
return(output)
}
# Define methods for analysis objects
eta_anova.aov <- function(x, ...) {
x_summary <- summary(x)
eta_anova(x_summary, ...)
}
eta_anova.summary.aov <- function(x, a = .05) {
x_df <- x[[1]]
output <- data.frame()
for(i in 1:(nrow(x_df) - 1)) {
output <- rbind(
output,
eta_anova(x_df[["F value"]][i], x_df[["Df"]][i], x_df[["Df"]][nrow(x_df)], a = a)
)
}
output <- cbind(effects = rownames(x_df)[1:(nrow(x_df) - 1)], output)
attr(output, "model") <- x
class(output) <- c("mote_anova", class(output))
output
}
# Run my analysis
aov_saved = aov(mpg~cyl * disp, data = mtcars)
aov_summary = summary(aov_saved)
# Process efficiently through MOTE
eta_anova(aov_summary[[1]][["F value"]][1], aov_summary[[1]][["Df"]][1], aov_summary[[1]][["Df"]][4], a = .05)
eta_anova(aov_saved)
eta_anova(aov_summary)
Adding the input object to the output facilitates interoperability with papaja
.
Does that make sense? If so feel free to use this (untested) code (a contributor note would be appreciated).