```
rate_keener(cr_data, ..., fill = 0, force_nonneg_h2h = TRUE,
skew_fun = skew_keener, normalize_fun = normalize_keener, eps = 0.001)
rank_keener(cr_data, ..., fill = 0, force_nonneg_h2h = TRUE,
skew_fun = skew_keener, normalize_fun = normalize_keener, eps = 0.001,
keep_rating = FALSE, ties = c("average", "first", "last", "random", "max",
"min"), round_digits = 7)
skew_keener(x)
normalize_keener(mat, cr_data)
```

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

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

fill | A single value to use instead of NA for missing pairs. |

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

skew_fun | Skew function. |

normalize_fun | Normalization function. |

eps | Coefficient for forcing irreducibility. |

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

ties | Value for |

round_digits | Value for |

x | Argument for |

mat | Argument for |

`rate_keener()`

returns a tibble with columns
`player`

(player identifier) and `rating_keener`

(Keener
rating). Sum of all ratings should be equal to 1. **Bigger
value indicates better player performance**.

`rank_keener()`

returns a `tibble`

with columns `player`

, `rating_keener`

(if
`keep_rating = TRUE`

) and `ranking_keener`

(Keener ranking
computed with `round_rank()`

).

`skew_keener()`

returns skewed vector of the same length as `x`

.

`normalize_keener()`

returns normalized matrix with the same dimensions as
`mat`

.

Keener rating method is based on Head-to-Head matrix of the competition results. Therefore it can be used for competitions with variable number of players. Its algorithm is as follows:

Compute Head-to-Head matrix of competition results based on Head-to-Head expression supplied in

`...`

(see h2h_mat() for technical details and section**Design of Head-to-Head values**for design details). Head-to-Head values are computed based only on the games between players of interest (see Players). Ensure that there are no`NA`

s by using`fill`

argument. If`force_nonneg_h2h`

is`TRUE`

then the minimum value is subtracted (in case some Head-to-Head value is strictly negative).Update raw Head-to-Head values (denoted as S) with the pair-normalization: a_ij = (S_ij + 1) / (S_ij + S_ji + 2). This step should make comparing different players more reasonable.

Skew Head-to-Head values with applying

`skew_fun`

to them.`skew_fun`

should take numeric vector as only argument. It should return skewed vector. The default skew function is`skew_keener()`

. This step should make abnormal results not very abnormal. To omit this step supply`skew_fun = NULL`

.Normalize Head-to-Head values with

`normalize_fun`

using`cr_data`

.`normalize_fun`

should take Head-to-Head matrix as the first argument and`cr_data`

as second. It should return normalized matrix. The default normalization is`normalize_keener()`

which divides Head-to-Head value of 'player1'-'player2' matchup divided by the number of games played by 'player1' (error is thrown if there are no games). This step should take into account possibly not equal number of games played by players. To omit this step supply`normalize_keener = NULL`

.Add small value to Head-to-Head matrix to ensure its irreducibility. 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`

. This step is done to ensure applicability of Perron-Frobenius theorem.Compute Perron-Frobenius vector of the resultant matrix, i.e. the strictly positive real eigenvector (which values sum to 1) for eigenvalue (which is real) of the maximum absolute value. This vector is Keener rating vector.

If using `normalize_keener()`

in normalization step, ensure to analyze
players which actually played games (as division by a number of played games
is made). If some player didn't play any game, en error is thrown.

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.

James P. Keener (1993) *The Perron-Frobenius theorem and the
ranking of football teams*. SIAM Review, 35(1):80–93, 1993.

```
#> # A tibble: 5 x 2
#> player rating_keener
#> <chr> <dbl>
#> 1 Duke 0.0671
#> 2 Miami 0.351
#> 3 UNC 0.158
#> 4 UVA 0.161
#> 5 VT 0.263 #> # A tibble: 5 x 2
#> player ranking_keener
#> <chr> <dbl>
#> 1 Duke 5
#> 2 Miami 1
#> 3 UNC 4
#> 4 UVA 3
#> 5 VT 2#> # A tibble: 5 x 3
#> player rating_keener ranking_keener
#> <chr> <dbl> <dbl>
#> 1 Duke 0.0671 5
#> 2 Miami 0.351 1
#> 3 UNC 0.158 4
#> 4 UVA 0.161 3
#> 5 VT 0.263 2#> # A tibble: 5 x 2
#> player rating_keener
#> <chr> <dbl>
#> 1 Duke 0.0898
#> 2 Miami 0.295
#> 3 UNC 0.165
#> 4 UVA 0.189
#> 5 VT 0.261 #> # A tibble: 5 x 2
#> player rating_keener
#> <chr> <dbl>
#> 1 Duke 0.162
#> 2 Miami 0.335
#> 3 UNC 0.136
#> 4 UVA 0.149
#> 5 VT 0.219#> # A tibble: 5 x 2
#> player rating_keener
#> <chr> <dbl>
#> 1 Duke 0.128
#> 2 Miami 0.300
#> 3 UNC 0.153
#> 4 UVA 0.161
#> 5 VT 0.257
```