Last active
December 3, 2022 12:50
-
-
Save ikashnitsky/aa56f8d30046c44d3f59c0047033e820 to your computer and use it in GitHub Desktop.
Were there too many sensations in Qatar? What if I bet the same amount against the odds in all the group-stage games?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#=============================================================================== | |
# 2022-12-03 -- misc | |
# World Cup games odds | |
# Ilya Kashnitsky, [email protected], @ikashnitsky | |
#=============================================================================== | |
library(tidyverse) | |
library(magrittr) | |
library(rvest) | |
library(ggrepel) | |
library(sysfonts) | |
library(showtext) | |
library(prismatic) | |
sysfonts::font_add_google("Atkinson Hyperlegible", "ah") | |
showtext_auto() | |
# Data come from: | |
# https://www.oddsportal.com/soccer/world/world-cup-2022/results/ | |
odds <- read_delim("https://gist.githubusercontent.com/ikashnitsky/aa56f8d30046c44d3f59c0047033e820/raw/fce43c649ec7c76357c7082577148551b9ef8574/raw-data.txt") %>% | |
set_names(letters[1:5]) %>% | |
filter(! seq_along(a) %in% c(seq(5, 55, 5), 59)) %>% | |
separate(b, into = c("team_1", "team_2"), sep = " - ") %>% | |
separate(c, into = c("goals_1", "goals_2")) %>% | |
separate(e, into = c("odds_draw", "odds_2", "waste"), sep = "\t") %>% | |
transmute( | |
team_1, team_2, | |
goals_1 = goals_1 %>% as.numeric, | |
goals_2 = goals_2 %>% as.numeric, | |
odds_1 = d, | |
odds_draw = odds_draw %>% as.numeric, | |
odds_2 = odds_2 %>% as.numeric | |
) | |
pred <- odds %>% | |
mutate( | |
outcome = case_when( | |
goals_1 > goals_2 ~ "team_1", | |
goals_1 < goals_2 ~ "team_2", | |
TRUE ~ "draw" | |
) | |
) %>% | |
group_by(id = 49 - seq_along(team_1)) %>% | |
mutate(my_bet = max(odds_1, odds_draw, odds_2)) %>% | |
ungroup() %>% | |
mutate( | |
winning_bet = case_when( | |
goals_1 > goals_2 ~ odds_1, | |
goals_1 < goals_2 ~ odds_2, | |
TRUE ~ odds_draw | |
), | |
# THE LOGIC: whenever I lose the bet, I just lose 1 coin | |
# whenever my unlikely bet works, I receive the odds amount | |
# minus my initially risked coin | |
win = case_when( | |
my_bet == winning_bet ~ my_bet - 1, | |
TRUE ~ -1 | |
) | |
) %>% | |
arrange(id) %>% | |
mutate( | |
cum = win %>% cumsum() | |
) | |
pred %>% | |
filter(my_bet == winning_bet) %>% | |
view() | |
set.seed(126) | |
pred %>% | |
ggplot(aes(id, cum))+ | |
geom_hline(yintercept = c(0), size = .5, color = 2)+ | |
# geom_step(aes(id, id), size = 1, color = 7, alpha = .75)+ | |
geom_step(color = "#444444", alpha = .5)+ | |
geom_point(data = . %>% filter(my_bet == winning_bet))+ | |
geom_text_repel( | |
data = . %>% filter(my_bet == winning_bet), | |
aes(label = paste(team_1, goals_1, ":", goals_2, team_2)), | |
size = 2.7, color = "#444444", hjust = 1, fontface = 2 | |
)+ | |
scale_x_continuous(breaks = c(seq(0, 40, 10),48), position = "top")+ | |
scale_y_continuous(position = "right")+ | |
labs( | |
x = "All the group-stage games of FIFA World Cup 2022, ordered chronologically", | |
y = "Net balance", | |
title = "Were there too many sensations in Qatar?", | |
caption = "\nData: oddsportal.com/soccer/world/world-cup-2022/results // Design: @[email protected]" | |
)+ | |
theme_minimal(base_family = "ah")+ | |
theme( | |
panel.grid.minor = element_blank(), | |
plot.background = element_rect(fill = "#dadada", color = NA), | |
plot.title = element_text(size = 22, face = 2, color = "#444444") | |
)+ | |
annotate( | |
"text", label = "Imagine, I put 1 coin per game betting against the odds" %>% str_wrap(32), | |
size = 6.7, color = 2 %>% clr_darken(), alpha = .85, | |
x = 1, y = 59, hjust = 0, vjust = 1, | |
family = "ah", lineheight = .9, fontface = 2 | |
)+ | |
annotate( | |
"text", label = "I start with a 0 net balance, and every game it reduces by one coin... unless a sensation happens and my balance increases as I win the unlikely bet" %>% str_wrap(42), | |
size = 4, color = 2 %>% clr_darken(), alpha = .85, | |
x = 1, y = 45, hjust = 0, vjust = 1, | |
family = "ah", lineheight = .9 | |
)+ | |
annotate( | |
"text", label = "If I'm above the zero line that means I'm in a net profit, benefiting from betting at the sensations" %>% str_wrap(35), | |
size = 4.4, color = 2 %>% clr_darken(), alpha = .75, | |
x = 47, y = 14, hjust = 1, vjust = 1, | |
family = "ah", lineheight = .9 | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Today, 02 Dec 1 X 2 B's | |
19.00 Cameroon - Brazil 01.00 8.93 5.32 1.36 18 | |
19.00 Serbia - Switzerland 02.03 2.58 3.36 2.85 18 | |
15.00 Ghana - Uruguay 00.02 4.49 3.82 1.79 18 | |
15.00 South Korea - Portugal 02.01 4.26 3.84 1.85 18 | |
Yesterday, 01 Dec 1 X 2 B's | |
19.00 Costa Rica - Germany 02.04 23.79 11.17 1.1 18 | |
19.00 Japan - Spain 02.01 7.04 4.49 1.49 18 | |
15.00 Canada - Morocco 01.02 4.78 3.49 1.84 18 | |
15.00 Croatia - Belgium 00.00 3.02 3.41 2.44 18 | |
30/Nov/22 1 X 2 B's | |
19.00 Poland - Argentina 00.02 8.2 4.57 1.44 18 | |
19.00 Saudi Arabia - Mexico 01.02 5.35 4.28 1.62 18 | |
15.00 Australia - Denmark 01.00 7.38 4.89 1.43 18 | |
15.00 Tunisia - France 01.00 6.01 3.92 1.62 18 | |
29/Nov/22 1 X 2 B's | |
19.00 Iran - USA 00.01 4.18 3.49 1.95 18 | |
19.00 Wales - England 00.03 8.81 4.45 1.43 18 | |
15.00 Ecuador - Senegal 01.02 2.48 3.08 3.23 18 | |
15.00 Netherlands - Qatar 02.00 1.21 7 14.51 18 | |
28/Nov/22 1 X 2 B's | |
19.00 Portugal - Uruguay 02.00 1.93 3.35 4.49 18 | |
16.00 Brazil - Switzerland 01.00 1.5 4.28 7.6 18 | |
13.00 South Korea - Ghana 02.03 2.76 3.13 2.8 18 | |
10.00 Cameroon - Serbia 03.03 5.3 3.77 1.71 18 | |
27/Nov/22 1 X 2 B's | |
19.00 Spain - Germany 01.01 2.54 3.42 2.84 18 | |
16.00 Croatia - Canada 04.01 2.23 3.27 3.55 18 | |
13.00 Belgium - Morocco 00.02 1.9 3.45 4.52 18 | |
10.00 Japan - Costa Rica 00.01 1.49 4.32 7.47 18 | |
26/Nov/22 1 X 2 B's | |
19.00 Argentina - Mexico 02.00 1.55 3.95 7.12 18 | |
16.00 France - Denmark 02.01 1.82 3.6 4.84 18 | |
13.00 Poland - Saudi Arabia 02.00 1.73 3.64 5.43 18 | |
10.00 Tunisia - Australia 00.01 2.21 3.32 3.52 18 | |
25/Nov/22 1 X 2 B's | |
19.00 England - USA 00.00 1.48 4.26 7.96 18 | |
16.00 Netherlands - Ecuador 01.01 1.83 3.44 4.99 18 | |
13.00 Qatar - Senegal 01.03 5.5 3.6 1.73 18 | |
10.00 Wales - Iran 00.02 2.14 3.18 3.87 18 | |
24/Nov/22 1 X 2 B's | |
19.00 Brazil - Serbia 02.00 1.47 4.57 7.23 18 | |
16.00 Portugal - Ghana 03.02 1.32 5.49 10.21 18 | |
13.00 Uruguay - South Korea 00.00 1.78 3.55 5.1 18 | |
10.00 Switzerland - Cameroon 01.00 1.81 3.45 5.02 18 | |
23/Nov/22 1 X 2 B's | |
19.00 Belgium - Canada 01.00 1.58 4.21 5.92 18 | |
16.00 Spain - Costa Rica 07.00 1.16 8.42 17.43 18 | |
13.00 Germany - Japan 01.02 1.45 4.85 7.28 18 | |
10.00 Morocco - Croatia 00.00 3.57 3.28 2.21 18 | |
22/Nov/22 1 X 2 B's | |
19.00 France - Australia 04.01 1.22 6.8 13.86 17 | |
16.00 Mexico - Poland 00.00 2.51 3.13 3.14 17 | |
13.00 Denmark - Tunisia 00.00 1.58 3.92 6.57 17 | |
10.00 Argentina - Saudi Arabia 01.02 1.12 9.21 25.52 17 | |
21/Nov/22 1 X 2 B's | |
19.00 USA - Wales 01.01 2.47 3.09 3.22 17 | |
16.00 Senegal - Netherlands 00.02 6.1 3.67 1.66 17 | |
13.00 England - Iran 06.02 1.38 4.65 10.2 17 | |
20/Nov/22 1 X 2 B's | |
16.00 Qatar - Ecuador 00.02 3.71 3.14 2.24 17 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment