/
fit.anova.R
77 lines (73 loc) · 2.43 KB
/
fit.anova.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#' @name .fit.anova
#' @title ANOVA for \code{tidyfit}
#' @description Performs Analysis of Variance on a 'tidyFit' \code{R6} class. The function can be used with \code{\link{regress}} or \code{\link{classify}}.
#'
#' @param self a 'tidyFit' R6 class.
#' @param data a data frame, data frame extension (e.g. a tibble), or a lazy data frame (e.g. from dbplyr or dtplyr).
#' @return A fitted 'tidyFit' class model.
#'
#' @details **Hyperparameters:**
#'
#' *None. Cross validation not applicable.*
#'
#' **Important method arguments (passed to \code{\link{m}})**
#'
#' The function provides a wrapper for \code{stats::anova}. See \code{?anova} for more details.
#'
#' First a \code{glm} model is fitted which is passed to \code{anova}.
#'
#' @author Johann Pfitzinger
#'
#' @examples
#' # Load data
#' data <- tidyfit::Factor_Industry_Returns
#'
#' # Stand-alone function
#' fit <- m("anova", Return ~ `Mkt-RF` + HML + SMB, data)
#' fit
#'
#' # Within 'regress' function
#' fit <- regress(data, Return ~ ., m("anova"), .mask = c("Date", "Industry"))
#' tidyr::unnest(coef(fit), model_info)
#'
#' @seealso \code{\link{.fit.lm}}, \code{\link{.fit.glm}} and \code{\link{m}} methods
#'
#' @importFrom stats anova
#' @importFrom purrr safely quietly
#' @importFrom methods formalArgs
.fit.anova <- function(
self,
data = NULL
) {
ctr <- self$args[names(self$args) %in% methods::formalArgs(stats::glm)]
mf <- stats::model.frame(self$formula, data)
x <- stats::model.matrix(self$formula, mf)
y <- stats::model.response(mf)
if (self$mode == "regression")
self$set_args(family = gaussian(), overwrite = FALSE)
if (self$mode == "classification") {
self$set_args(family = binomial(), overwrite = FALSE)
class_names_map <- levels(y)
names(class_names_map) <- 1:length(levels(y))
mf[, 1] <- as.numeric(as.factor(y)) - 1
}
ctr <- self$args[names(self$args) %in% methods::formalArgs(stats::glm)]
eval_fun_ <- function(...) {
args <- list(...)
mod <- do.call(stats::glm, args)
stats::anova(mod)
}
eval_fun <- purrr::safely(purrr::quietly(eval_fun_))
res <- do.call(eval_fun,
append(list(formula = self$formula, data = mf), ctr))
.store_on_self(self, res)
if (self$mode == "classification") {
self$fit_info <- list(class_names_map = class_names_map)
}
self$estimator <- "stats::anova"
invisible(self)
}
.coef.anova <- function(object, self = NULL, ...) {
estimates <- broom::tidy(object)
return(estimates)
}