```
rate_od(cr_data, ..., force_nonneg_h2h = TRUE, eps = 0.001, tol = 1e-04,
max_iterations = 100)
rank_od(cr_data, ..., force_nonneg_h2h = TRUE, eps = 0.001, tol = 1e-04,
max_iterations = 100, keep_rating = FALSE, ties = c("average", "first",
"last", "random", "max", "min"), round_digits = 7)
```

cr_data | Competition results in format ready for as_longcr(). |
---|---|

... | Head-to-Head expression (see h2h_mat()). |

force_nonneg_h2h | Whether to force nonnegative values in Head-to-Head matrix. |

eps | Coefficient for total support. |

tol | Tolerance value for iterative algorithm. |

max_iterations | Maximum number of iterations for iterative algorithm. |

keep_rating | Whether to keep rating columns in ranking output. |

ties | Value for |

round_digits | Value for |

`rate_od()`

returns a tibble with the following
columns:

**player**- player identifier.**rating_off**- offensive rating of player.**Bigger value indicates better player performance**.**rating_def**- defensive rating of player.**Smaller value indicates better player performance**.**rating_od**- Offense-Defense rating of player.**Bigger value indicates better player performance**.

`rank_od()`

returns a `tibble`

of the similar structure as `rate_od()`

:

**player**- player identifier.**rating_off**,**rating_def**,**rating_od**- ratings (if`keep_rating = TRUE`

).**ranking_off**,**ranking_def**,**ranking_od**- rankings computed with`round_rank()`

.

Offense-Defense (OD) rating is designed for games in which player's
goal is to make higher score than opponent(s). To describe competition
results Head-to-Head matrix is computed using `...`

(see
h2h_mat() for technical details and section **Design
of Head-to-Head values** for design details). For pairs of players without
common games Head-to-Head value is computed to 0 (not `NA`

). **Note** that
values should be non-negative and non-NA. This can be ensured with setting
`force_nonneg_h2h`

to `TRUE`

.

For player which can achieve *high* Head-to-Head value (even against the
player with strong defense) it is said that he/she has **strong offense**
which results into *high* offensive rating. For player which can force their
opponents into achieving *low* Head-to-Head value (even if they have strong
offense) it is said that he/she has **strong defense** which results into
*low* defensive rating.

Offensive and defensive ratings describe different skills of players. In order to fully rate players, OD ratings are computed: offensive ratings divided by defensive. The more OD rating the better player performance.

Algorithm for OD ratings is as follows:

Compute Head-to-Head matrix using

`...`

.Add small value to Head-to-Head matrix to ensure convergence of the iterative algorithm in the next step. If all values are strictly positive then this step is omitted. In other case small value is computed as the smallest non-zero Head-to-Head value multiplied by

`eps`

.Perform iterative fixed point search with the following recurrent formula:

`def_{k+1} = t(A) %*% inv(A %*% inv(def_{k}))`

where`def_{k}`

is a vector of defensive ratings at iteration`k`

,`A`

is a perturbed Head-to-Head matrix,`inv(x) = 1 / x`

. Iterative search stops if at least one of two conditions is met:`sum(abs(def_{k+1} / def_{k} - 1)) < tol`

.Number of iterations exceeds maximum number of iterations

`max_iterations`

.

Compute offensive ratings:

`off = A %*% inv(def)`

.Compute OD ratings:

`od = off / def`

.

Ratings are computed based only on games between players of interest (see Players). However, be careful with OD ratings for players with no games: they will have weak offense (because they "scored" 0 in all games) but strong defense (because all their opponents also "scored" 0 in all common games). Therefore accounting for missing players might be not a very good idea.

Head-to-Head values in these functions are assumed to follow the property
which can be *equivalently* described in two ways:

In terms of matrix format:

**the more Head-to-Head value in row**.*i*and column*j*the better player from row*i*performed than player from column*j*In terms of long format:

**the more Head-to-Head value the better player1 performed than player2**.

This design is chosen because in most competitions the goal is to score
**more points** and not less. Also it allows for more smooth use of
h2h_funs from `comperes`

package.

`comperank`

offers a possibility to handle certain set of players. It is done
by having `player`

column (in longcr format) as factor
with levels specifying all players of interest. In case of factor the result
is returned only for players from its levels. Otherwise - for all present
players.

Amy N. Langville, Carl D. Meyer (2012) *Who’s #1?: The
science of rating and ranking*.

Philip A. Knight (2008) *The Sinkhorn-Knopp algorithm:
Convergence and applications.*. SIAM Journal of Matrix Analysis,
30(1):261–275, 2008 (For stopping rule of iterative algorithm).

```
rate_od(ncaa2005, mean(score1))#> # A tibble: 5 x 4
#> player rating_off rating_def rating_od
#> <chr> <dbl> <dbl> <dbl>
#> 1 Duke 39.7 1.57 25.3
#> 2 Miami 181. 0.860 211.
#> 3 UNC 58.1 1.15 50.6
#> 4 UVA 95.0 0.914 104.
#> 5 VT 183. 0.532 344.
rank_od(ncaa2005, mean(score1))#> # A tibble: 5 x 4
#> player ranking_off ranking_def ranking_od
#> <chr> <dbl> <dbl> <dbl>
#> 1 Duke 5 5 5
#> 2 Miami 2 2 2
#> 3 UNC 4 4 4
#> 4 UVA 3 3 3
#> 5 VT 1 1 1
rank_od(ncaa2005, mean(score1), keep_rating = TRUE)#> # A tibble: 5 x 7
#> player rating_off rating_def rating_od ranking_off ranking_def ranking_od
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Duke 39.7 1.57 25.3 5 5 5
#> 2 Miami 181. 0.860 211. 2 2 2
#> 3 UNC 58.1 1.15 50.6 4 4 4
#> 4 UVA 95.0 0.914 104. 3 3 3
#> 5 VT 183. 0.532 344. 1 1 1
# Account for self play
rate_od(ncaa2005, if(player1[1] == player2[1]) 0 else mean(score1))#> # A tibble: 5 x 4
#> player rating_off rating_def rating_od
#> <chr> <dbl> <dbl> <dbl>
#> 1 Duke 34.0 1.69 20.1
#> 2 Miami 152. 0.803 189.
#> 3 UNC 48.7 1.16 41.8
#> 4 UVA 82.0 0.967 84.8
#> 5 VT 115. 0.411 280.
```