```
rate_markov(cr_data, ..., fill = list(), stoch_modify = teleport(0.15),
weights = 1, force_nonneg_h2h = TRUE)
rank_markov(cr_data, ..., fill = list(), stoch_modify = teleport(0.15),
weights = 1, force_nonneg_h2h = TRUE, keep_rating = FALSE,
ties = c("average", "first", "last", "random", "max", "min"),
round_digits = 7)
```

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

... | Name-value pairs of Head-to-Head functions (see h2h_long()). |

fill | A named list that for each Head-to-Head function supplies a single value to use instead of NA for missing pairs (see h2h_long()). |

stoch_modify | A single function to modify column-stochastic matrix or a list of them (see Stochastic matrix modifiers). |

weights | Weights for different stochastic matrices. |

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

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

ties | Value for |

round_digits | Value for |

`rate_markov()`

returns a tibble with columns
`player`

(player identifier) and `rating_markov`

(Markov
rating). The sum of all ratings should be equal to 1.
**Bigger value indicates better player performance**.

`rank_markov`

returns a `tibble`

with columns `player`

, `rating_markov`

(if
`keep_rating = TRUE`

) and `ranking_markov`

(Markov ranking
computed with `round_rank()`

).

Markov ratings are based on players 'voting' for other players being better. Algorithm is as follows:

'Voting' is done with Head-to-Head values supplied in

`...`

(see h2h_mat() for technical details and section**Design of Head-to-Head values**for design details). Take special care of Head-to-Head values for self plays (when player1 equals player2).**Note**that Head-to-Head values should be non-negative. Use`force_nonneg_h2h = TRUE`

to force that by subtracting minimum Head-to-Head value (in case some Head-to-Head value is strictly negative).Head-to-Head values are transformed into matrix which is normalized to be column-stochastic (sum of every column should be equal to 1) Markov matrix

*S*.**Note**that all missing values are converted into 0. To specify other value use`fill`

argument.*S*is modified with`stoch_modify`

to deal with possible problems behind*S*, such as reducibility and rows with all 0.Stationary vector is computed based on

*S*as probability transition matrix of Markov chain process (transition probabilities from state**i**are elements from column**i**). The result is declared as Markov ratings.

Considering common values and structure of stochastic matrices one can naturally combine different 'votings' in one stochastic matrix:

Long format of Head-to-Head values is computed using

`...`

(which in this case should be several expressions for Head-to-Head functions).Each set of Head-to-Head values is transformed into matrix which is normalized to column-stochastic.

Each stochastic matrix is modified with respective modifier which is stored in

`stoch_modify`

(which can be a list of functions).The resulting stochastic matrix is computed as weighted average of modified stochastic matrices.

For Head-to-Head functions in `...`

(considered as list) and argument
`stoch_modify`

general R recycling rule is applied. If `stoch_modify`

is a
function it is transformed to list with one function.

`weights`

is recycled to the maximum length of two mentioned recycled
elements and then is normalized to sum to 1.

Ratings are computed based only on games between players of interest (see Players).

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.

Wikipedia page for Markov chain.

```
rate_markov(
cr_data = ncaa2005,
# player2 "votes" for player1 if player1 won
comperes::num_wins(score1, score2, half_for_draw = FALSE),
stoch_modify = vote_equal
)#> # A tibble: 5 x 2
#> player rating_markov
#> <chr> <dbl>
#> 1 Duke 0.0876
#> 2 Miami 0.438
#> 3 UNC 0.146
#> 4 UVA 0.109
#> 5 VT 0.219
rank_markov(
cr_data = ncaa2005,
comperes::num_wins(score1, score2, half_for_draw = FALSE),
stoch_modify = vote_equal
)#> # A tibble: 5 x 2
#> player ranking_markov
#> <chr> <dbl>
#> 1 Duke 5
#> 2 Miami 1
#> 3 UNC 3
#> 4 UVA 4
#> 5 VT 2
rank_markov(
cr_data = ncaa2005,
comperes::num_wins(score1, score2, half_for_draw = FALSE),
stoch_modify = vote_equal,
keep_rating = TRUE
)#> # A tibble: 5 x 3
#> player rating_markov ranking_markov
#> <chr> <dbl> <dbl>
#> 1 Duke 0.0876 5
#> 2 Miami 0.438 1
#> 3 UNC 0.146 3
#> 4 UVA 0.109 4
#> 5 VT 0.219 2
# Combine multiple stochastic matrices and
# use inappropriate `fill` which misrepresents reality
rate_markov(
cr_data = ncaa2005[-(1:2), ],
win = comperes::num_wins(score1, score2, half_for_draw = FALSE),
# player2 "votes" for player1 proportionally to the amount player1 scored
# more in direct confrontations
score_diff = max(mean(score1 - score2), 0),
fill = list(win = 0.5, score_diff = 10),
stoch_modify = list(vote_equal, teleport(0.15)),
weights = c(0.8, 0.2)
)#> # A tibble: 5 x 2
#> player rating_markov
#> <chr> <dbl>
#> 1 Duke 0.305
#> 2 Miami 0.308
#> 3 UNC 0.103
#> 4 UVA 0.0936
#> 5 VT 0.191
```