62 |
63 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
133 |
134 | Content not found. Please use links in the navbar.
135 |
136 |
137 |
138 |
143 |
144 |
145 |
146 |
147 |
148 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
--------------------------------------------------------------------------------
/R/elo.model.frame.R:
--------------------------------------------------------------------------------
1 |
2 | #' Interpret formulas in \code{elo} functions
3 | #'
4 | #' A helper function to create the \code{model.frame} for many \code{elo} functions.
5 | #'
6 | #' @param formula A formula. See \link[=formula.specials]{the help page for formulas} for details.
7 | #' @param data A \code{data.frame} in which to look for objects in \code{formula}.
8 | #' @param na.action A function which indicates what should happen when the data contain NAs.
9 | #' @param subset An optional vector specifying a subset of observations.
10 | #' @param k A constant k-value (or a vector, where appropriate).
11 | #' @param ... Other arguments (not in use at this time).
12 | #' @param required.vars One or more of \code{c("wins", "elos", "k", "group", "regress")},
13 | #' denoting which variables are required to appear in the final model.frame.
14 | #' @param warn.k Should a warning be issued if \code{k} is specified as an argument and in \code{formula}?
15 | #' @param ncol.k How many columns (\code{NCOL}) should \code{k} have?
16 | #' @param ncol.elos How many Elo columns are expected?
17 | #' @seealso \code{\link{elo.run}}, \code{\link{elo.calc}}, \code{\link{elo.update}}, \code{\link{elo.prob}}
18 | #' @export
19 | elo.model.frame <- function(formula, data, na.action, subset, k = NULL, ..., required.vars = "elos", warn.k = TRUE, ncol.k = 1, ncol.elos = 2)
20 | {
21 | Call <- match.call()
22 | required.vars <- match.arg(required.vars, c("wins", "elos", "k", "group", "regress", "neutral", "weights"), several.ok = TRUE)
23 | indx <- match(c("formula", "data", "subset", "na.action", "weights"), names(Call), nomatch = 0)
24 | if(indx[1] == 0) stop("A formula argument is required.")
25 |
26 | temp.call <- Call[c(1, indx)]
27 | temp.call[[1L]] <- quote(stats::model.frame)
28 | specials <- c("adjust", "k", "group", "regress", "neutral", "players")
29 |
30 | temp.call$formula <- if(missing(data))
31 | {
32 | stats::terms(formula, specials)
33 | } else stats::terms(formula, specials, data = data)
34 |
35 | mf <- eval(temp.call, parent.frame())
36 | if(nrow(mf) == 0) stop("No (non-missing) observations")
37 |
38 | Terms <- stats::terms(mf)
39 | naaction <- stats::na.action(mf)
40 |
41 | #####################################################################
42 |
43 | has.wins <- attr(Terms, "response") == 1
44 |
45 | k.col <- attr(Terms, "specials")$k
46 | has.k <- !null_or_length0(k.col) || !is.null(k)
47 |
48 | grp.col <- attr(Terms, "specials")$group
49 | reg.col <- attr(Terms, "specials")$regress
50 | neu.col <- attr(Terms, "specials")$neutral
51 | wts.col <- which(names(mf) == "(weights)")
52 |
53 | if("wins" %in% required.vars && !has.wins)
54 | {
55 | stop("A 'wins' component is required in the left-hand side of 'formula'.")
56 | }
57 |
58 | if("k" %in% required.vars && !has.k)
59 | {
60 | stop("'k' is not in 'formula' or specified as an argument.")
61 | } else if(!null_or_length0(k.col) && !is.null(k) && warn.k)
62 | {
63 | warning("'k = ' argument being ignored.")
64 | }
65 |
66 | # need all the parens b/c ! is a low-precident operator
67 | sum.nonempty <- (!null_or_length0(k.col)) + (!null_or_length0(grp.col)) + (!null_or_length0(reg.col)) +
68 | (!null_or_length0(neu.col)) + (!null_or_length0(wts.col))
69 |
70 | if(has.wins + sum.nonempty + ncol.elos != ncol(mf))
71 | {
72 | stop("'formula' not specified correctly: found ", ncol(mf), " columns; expected ",
73 | has.wins + sum.nonempty + ncol.elos)
74 | }
75 |
76 | # figure out which columns are the "real" ones
77 | elo.cols <- if(sum.nonempty == 0)
78 | {
79 | (1:ncol.elos) + has.wins
80 | } else setdiff(1:ncol(mf), c(if(has.wins) 1, k.col, grp.col, reg.col, neu.col, wts.col))
81 | stopifnot(ncol.elos %in% 1:2)
82 | if(length(elo.cols) != ncol.elos) stop("Trouble finding the Elo columns.")
83 |
84 | #####################################################################
85 |
86 | out <- data.frame(row.names = 1:nrow(mf)) # in case one of the next two lines is a matrix
87 | out$elo.A <- remove_elo_adjust(mf[[elo.cols[1]]])
88 | if(ncol.elos == 2) out$elo.B <- remove_elo_adjust(mf[[elo.cols[2]]])
89 |
90 | if("wins" %in% required.vars)
91 | {
92 | out$wins.A <- as.numeric(mf[[1]])
93 | if(!(is.mov <- inherits(mf[[1]], "elo.mov"))) validate_score(out$wins.A)
94 | } else is.mov <- FALSE
95 | if("k" %in% required.vars)
96 | {
97 | k <- if(null_or_length0(k.col))
98 | {
99 | if(!(length(k) %in% c(1, nrow(mf)))) stop("'k' must be length 1 or the number of rows of data")
100 | if(length(k) == 1) k <- rep(k, nrow(mf))
101 | k
102 | } else mf[[k.col]]
103 | stopifnot(ncol.k %in% 1:2)
104 | if(ncol.k == 2 && NCOL(k) == 1) k <- matrix(c(k, k), ncol = 2)
105 | out$k <- k
106 | if(!is.numeric(out$k) || anyNA(out$k)) stop("'k' should be numeric and non-NA.")
107 | }
108 | if("group" %in% required.vars)
109 | {
110 | out$group <- if(null_or_length0(grp.col)) TRUE else mf[[grp.col]]
111 | }
112 | if("regress" %in% required.vars)
113 | {
114 | out$regress <- if(null_or_length0(reg.col))
115 | {
116 | regress(rep(FALSE, times = nrow(out)), 1500, 0, FALSE)
117 | } else mf[[reg.col]]
118 | }
119 | if("neutral" %in% required.vars)
120 | {
121 | out$home.field <- if(null_or_length0(neu.col)) rep(1, times = nrow(out)) else 1 - mf[[neu.col]]
122 | }
123 | if("weights" %in% required.vars)
124 | {
125 | out$weights <- if(null_or_length0(wts.col))
126 | {
127 | rep(1, times = nrow(out))
128 | } else mf[["(weights)"]]
129 | }
130 |
131 | adjs <- attr(Terms, "specials")$adjust
132 |
133 | out$adj.A <- if(null_or_length0(adjs) || !any(adjs == elo.cols[1])) 0 else attr(fix_adjust(mf[[elo.cols[1]]], naaction), "adjust")
134 | if(ncol.elos == 2) out$adj.B <- if(null_or_length0(adjs) || !any(adjs == elo.cols[2])) 0 else attr(fix_adjust(mf[[elo.cols[2]]], naaction), "adjust")
135 |
136 | if(!is.numeric(out$adj.A) || (!is.null(out$adj.B) && !is.numeric(out$adj.B))) stop("Any Elo adjustments should be numeric!")
137 |
138 | attr(out, "terms") <- Terms
139 | attr(out, "na.action") <- naaction
140 | attr(out, "outcome") <- if(is.mov) "mov" else "score"
141 | out
142 | }
143 |
--------------------------------------------------------------------------------
/docs/articles/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |