diff --git a/.DS_Store b/.DS_Store
index b06a9fd..4b2dabf 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/app/src/assets/bramka.jpeg b/app/src/assets/bramka.jpeg
new file mode 100644
index 0000000..b2040fd
Binary files /dev/null and b/app/src/assets/bramka.jpeg differ
diff --git a/app/src/components/Hero.jsx b/app/src/components/Hero.jsx
index 5cdf92e..b61daee 100644
--- a/app/src/components/Hero.jsx
+++ b/app/src/components/Hero.jsx
@@ -148,18 +148,18 @@ const Hero = () => {
// div z nazwa gracza
var tekst = document.createElement('div')
- tekst.style.fontSize = "10px";
+ tekst.style.fontSize = "12px";
tekst.innerHTML = pName;
// div z pozycja gracza
var posytion = document.createElement('div')
- posytion.style.fontSize = "10px"
- posytion.innerHTML = "x:" + konwerturX(ball.style.left) + "m " + "y:" + konwetujY(ball.style.top) + "m";
+ posytion.style.fontSize = "12px"
+ posytion.innerHTML = "Lokalizacja: " + konwerturX(ball.style.left) + " m, " + konwetujY(ball.style.top) + " m";
player.setAttribute('possition',[konwerturX(ball.style.left),konwetujY(ball.style.top)])
//div z przyciskiem usuwającym
var btnDelete = document.createElement('button')
- btnDelete.innerHTML = 'Usun'
- btnDelete.style.fontSize = "10px"
+ btnDelete.innerHTML = 'Usuń'
+ btnDelete.style.fontSize = "12px"
btnDelete.style = 'background-color: #FFB266;color:#000000'
btnDelete.addEventListener("click",function(){deletePlayer(ball,player,possition)},false)
//dodanie elementów do kafelka
@@ -219,6 +219,7 @@ const Hero = () => {
//var shooterX = konwerturX(ball.style.left)
//var shooterY = konwetujY(ball.style.top)
posytion.innerHTML = "x:" + konwerturX(ball.style.left) + "m " + "y:" + konwetujY(ball.style.top) + "m";
+ //player.setAttribute('possition',[konwerturX(ball.style.left),konwetujY(ball.style.top)]);
bojo.addEventListener("mouseup", function(){
ball.style.background = pColor
bojo.removeEventListener("mousemove", whileMove)
@@ -229,6 +230,11 @@ const Hero = () => {
})
}
+ function updateXGMeter(xgValue) {
+ var xgMeter = document.querySelector('.xg-meter');
+ var greenIntensity = xgValue * 100; // Zakładając, że xgValue jest między 0 a 1
+ //xgMeter.style.background = `linear-gradient(to top, #006400 ${greenIntensity}%, #90EE90)`;
+}
// // Wyłanie zapytania do serwera
@@ -236,6 +242,7 @@ const Hero = () => {
///Dziwny Blad
loadPlayers()
if (number_of_shooters == 1) {
+ console.log('Wysyłanie wartości: ', bodyPart, technique);
// Użyj backticksów zamiast zwykłych cudzysłowów
fetch(`http://127.0.0.1:5000/get_model?shooter=${shooter}&goalkeeper=${goalkeeper}&defenders=${defenders}&strickers=${stricers}&bodyPart=${bodyPart}&technique=${technique}&actionType=${actionType}&shooterPossition=${shooterPossition}`).then(
res => res.json()
@@ -245,7 +252,8 @@ const Hero = () => {
console.log(data);
// Przenieś tę linię do środka bloku .then(), aby uniknąć błędów
let eX = data.response;
- document.getElementById("ex").innerHTML = "Współczynnik xG: " + eX;
+ document.getElementById("ex").innerHTML = eX;
+ updateXGMeter(eX);
}
).catch(error => {
console.error('Błąd:', error);
@@ -275,6 +283,7 @@ const Hero = () => {
ball.style.top = y + "%"
//dodanie zawodnika do listy oraz punktu do mapy w zaleznosci od aktywnosci przycisku 1,2,3 lub 4
+
if(active_bbt=="bbt1"){
if(number_of_shooters < 1 ){
addPlayer(0,ball)
@@ -283,7 +292,6 @@ const Hero = () => {
setNumberOfShooters(number_of_shooters+1)
}else{alert("mozesz dodac tylko jednego strzelca")}
}else if(active_bbt == "bbt2"){
-
if ( number_of_goalkeepers < 1){
addPlayer(1,ball)
bojo.appendChild(ball)
@@ -358,7 +366,7 @@ const Hero = () => {
-
+
@@ -371,18 +379,37 @@ const Hero = () => {
-
@@ -410,6 +437,36 @@ const Hero = () => {
+
+
Parametry strzału
+
+
+
+
+
+
+
+
+
+
{/*
@@ -436,13 +493,11 @@ const Hero = () => {
-
-
);
};
diff --git a/app/src/components/Loader.jsx b/app/src/components/Loader.jsx
index 4abbec8..1153e4e 100644
--- a/app/src/components/Loader.jsx
+++ b/app/src/components/Loader.jsx
@@ -3,6 +3,7 @@ import React from 'react'
const Loader = () => {
return (
Loader
+
)
}
diff --git a/app/src/flask-server/modele/__pycache__/modele.cpython-39.pyc b/app/src/flask-server/modele/__pycache__/modele.cpython-39.pyc
index 1361d5f..616f5ef 100644
Binary files a/app/src/flask-server/modele/__pycache__/modele.cpython-39.pyc and b/app/src/flask-server/modele/__pycache__/modele.cpython-39.pyc differ
diff --git a/app/src/index.css b/app/src/index.css
index 70a3c0b..6ea3dc1 100644
--- a/app/src/index.css
+++ b/app/src/index.css
@@ -4,19 +4,55 @@
@tailwind components;
@tailwind utilities;
- .Ex{
- display: block; /* Może być inline-block, jeśli preferujesz */
- margin: 20px auto; /* Centralnie i z marginesem */
- padding: 10px;
- background-color: #4CAF50; /* Przykładowy kolor tła */
- color: white; /* Kolor tekstu */
- text-align: center;
- border-radius: 5px; /* Lekko zaokrąglone rogi */
- font-size: 20px; /* Duża, czytelna czcionka */
- font-weight: bold; /* Pogrubienie dla lepszej widoczności */
- width: 50%; /* Dostosuj szerokość zgodnie z potrzebami */
- /* Dodatkowe style, takie jak cienie, mogą być dodane */
- }
+ .Ex {
+ display: block; /* Może być inline-block, jeśli preferujesz */
+ margin: 20px auto; /* Centralnie i z marginesem */
+ padding: 10px;
+ background-color: #4CAF50; /* Przykładowy kolor tła */
+ color: white; /* Kolor tekstu */
+ text-align: center;
+ border-radius: 5px; /* Lekko zaokrąglone rogi */
+ font-size: 20px; /* Duża, czytelna czcionka */
+ font-weight: bold; /* Pogrubienie dla lepszej widoczności */
+ width: 100%; /* Poszerzone pole */
+ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.5); /* Cień dla dodatkowej głębi */
+ /* Opcjonalnie, można dodać gradient tła dla większego efektu */
+ background-image: linear-gradient(to right, #32CD32 , #4CAF50);
+ transition: transform 0.3s ease; /* Delikatna animacja */
+ }
+
+ .Ex:hover {
+ transform: scale(1.10); /* Efekt powiększenia przy najechaniu */
+ }
+
+.xg-meter {
+ width: 200px;
+ height: 100px; /* Zmiana wysokości, aby pasowała do proporcji bramki */
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ color: white;
+ font-size: 48px;
+ font-weight: bold;
+ background: url('assets/bramka.jpeg') no-repeat center center; /* Tło z obrazem bramki */
+ background-size: cover; /* Dopasowanie obrazu do rozmiaru elementu */
+ border-radius: 10px; /* Opcjonalnie, dla zaokrąglonych rogów */
+}
+
+.xg-value {
+ display: block;
+ background: rgba(0, 0, 0, 0.5); /* Półprzezroczyste tło dla lepszej czytelności tekstu */
+ padding: 5px 10px; /* Dodanie odstępu */
+ border-radius: 5px; /* Zaokrąglone rogi dla tekstu */
+}
+
+
+/* Funkcja JavaScript będzie sterować stopniem gradientu */
+
+
+
+
body {
margin: 50px;
display: grid;
@@ -25,7 +61,7 @@
grid-template-rows: auto;
grid-template-columns: auto auto auto;
}
-
+
.container {
display: flex;
flex-direction: column;
@@ -49,19 +85,20 @@
max-height: 100%;
}
-
+
.container span {
display: block;
}
-
- .main-content {
-
- display: flex;
- justify-content: space-between;
- align-items: center;
-
-
-}
+
+ .main-content {
+
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+
+ }
+
.player{
width: inherit;
height: 8vh;
@@ -84,7 +121,7 @@
background-color: #cccccc;
justify-content: space-between;
}
-
+
.subMenu {
display: grid;
grid-template-rows: auto auto auto;
@@ -95,14 +132,15 @@
background-color: #f0f0f0; /* Example background color */
z-index: 1000; /* Ensure it stays on top of other content */
}
- .player-list{
+
+ .player-list {
background-color: rgb(61, 38, 38);
width: 13vw;
height: calc(50vw*68/105);
overflow: scroll;
-
-
+ font-size: 12px; /* Example font size - adjust as needed */
}
+
.top-bar {
display: flex;
justify-content: space-between;
@@ -112,7 +150,7 @@
/* Możesz dodać dodatkowe style, jak tło, obramowanie itp. */
z-index: 2;
}
-
+
.bottom-bar {
display: flex;
justify-content: space-between; /* Rozmieszcza przyciski równomiernie */
@@ -128,7 +166,7 @@
border-radius: 50%;
position: absolute
}
-
+
.reset-button {
position: relative;
margin: 5px;
@@ -200,7 +238,7 @@
color: #000000;
font-size: 16px;
}
-
+
.cho-first_time {
position: relative;
padding: 10px;
@@ -237,7 +275,38 @@
color: #000000;
font-size: 16px;
}
-
+
+.additional-parameters {
+ position: fixed; /* Or absolute, depending on layout */
+ right: 0;
+ top: 30%; /* Adjusted to a higher position */
+ width: 250px; /* Increased width */
+ background-color: #000000;
+ padding: 15px; /* Increased padding */
+ border: 1px solid #ddd;
+ border-radius: 5px;
+ box-shadow: 0 2px 5px rgba(0,0,0,0.2);
+ z-index: 100; /* To ensure it stays on top */
+ color: #ffffff; /* Optional: change text color for better visibility on dark background */
+}
+
+.additional-parameters h3 {
+ margin-top: 0;
+ font-size: 18px; /* Increased font size for heading */
+}
+
+.additional-parameters label {
+ display: flex; /* Updated to flex for better alignment */
+ align-items: center; /* Aligns checkbox and label text vertically */
+ margin-bottom: 10px; /* Increased spacing between checkboxes */
+ font-size: 16px; /* Increased font size for labels */
+}
+
+.additional-parameters input[type="checkbox"] {
+ margin-right: 10px; /* Adds spacing between checkbox and label text */
+}
+
+
/* DROPDOWNS */
/* Style the dropdown button */
.dropbtn {
@@ -253,13 +322,13 @@
.dropbtn:hover, .dropbtn:focus {
background-color: #3e8e41;
}
-
+
/* The container - needed to position the dropdown content */
.dropdown {
position: relative;
display: inline-block;
}
-
+
.cho-dropdown_body_part {
display: none;
position: absolute;
@@ -268,7 +337,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
-
+
.cho-dropdown_body_part a{
color: black;
padding: 12px 16px;
@@ -276,15 +345,15 @@
display: block;
font-size: 16px;
}
-
+
/* Change color of dropdown links on hover */
.cho-dropdown_body_part a:hover {background-color: #f1f1f1}
-
+
/* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_body_part {
display: block;
}
-
+
.cho-dropdown_position_name {
display: none;
position: absolute;
@@ -293,7 +362,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
-
+
.cho-dropdown_position_name a {
color: black;
padding: 12px 16px;
@@ -301,15 +370,15 @@
display: block;
font-size: 16px;
}
-
+
/* Change color of dropdown links on hover */
.cho-dropdown_position_name a:hover {background-color: #f1f1f1}
-
+
/* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_position_name {
display: block;
}
-
+
.cho-dropdown_technique_name {
position: relative;
display: none;
@@ -319,7 +388,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
-
+
.cho-dropdown_technique_name a {
color: black;
padding: 12px 16px;
@@ -327,15 +396,15 @@
display: block;
font-size: 16px;
}
-
+
/* Change color of dropdown links on hover */
.cho-dropdown_technique_name a:hover {background-color: #f1f1f1}
-
+
/* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_technique_name {
display: block;
}
-
+
.cho-dropdown_type_name {
display: none;
position: absolute;
@@ -344,7 +413,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
-
+
.cho-dropdown_type_name a {
color: black;
padding: 12px 16px;
@@ -352,16 +421,16 @@
display: block;
font-size: 16px;
}
-
+
/* Change color of dropdown links on hover */
.cho-dropdown_type_name a:hover {background-color: #f1f1f1}
-
+
/* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_type_name {
display: block;
}
-
-
+
+
/* MANUAL INPUT */
.cho-minute {
margin-top: 10px;
@@ -574,5 +643,5 @@
-2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff;
}
-
+
}
diff --git a/notebooks/dataCleaning.R b/notebooks/dataCleaning.R
index 29aa883..3d5ef73 100644
--- a/notebooks/dataCleaning.R
+++ b/notebooks/dataCleaning.R
@@ -11,33 +11,33 @@ library(purrr)
# code and data from https://github.com/Dato-Futbol/xg-model
get_shots <- function(file_path, name_detail, save_files = F){
-
+
players <- fromJSON("data/players.json")
-
+
shots <- fromJSON(file_path) %>%
filter(subEventName == "Shot")
-
+
tags <- tibble(tags = shots$tags) %>%
- hoist(tags,
+ hoist(tags,
tags_id = "id") %>%
unnest_wider(tags_id, names_sep = "")
-
+
tags2 <- tags %>%
mutate(is_goal = ifelse(rowSums(. == "101", na.rm = T) > 0, 1, 0),
is_blocked = ifelse(rowSums(. == "2101", na.rm = T) > 0, 1, 0),
is_CA = ifelse(rowSums(. == "1901", na.rm = T) > 0, 1, 0), # is countre attack
- body_part = ifelse(rowSums(. == "401", na.rm = T) > 0, "left",
- ifelse(rowSums(. == "402", na.rm = T) > 0, "right",
+ body_part = ifelse(rowSums(. == "401", na.rm = T) > 0, "left",
+ ifelse(rowSums(. == "402", na.rm = T) > 0, "right",
ifelse(rowSums(. == "403", na.rm = T) > 0, "head/body", "NA"))))
-
+
pos <- tibble(positions = shots$positions) %>%
- hoist(positions,
+ hoist(positions,
y = "y",
x = "x") %>%
unnest_wider(y, names_sep = "") %>%
unnest_wider(x, names_sep = "") %>%
dplyr::select(-c(x2, y2))
-
+
shots_ok <- shots %>%
dplyr::select(matchId, teamId, playerId, eventSec, matchPeriod) %>%
bind_cols(pos, tags2) %>%
@@ -46,14 +46,14 @@ get_shots <- function(file_path, name_detail, save_files = F){
left_join(players %>%
dplyr::select(c("wyId", "foot")), by = c("playerId" = "wyId")) %>%
mutate(league = name_detail)
-
+
if(save_files){
write_rds(shots, paste0("shots", name_detail, ".rds"))
write_rds(tags2, paste0("tags2", name_detail, ".rds"))
write_rds(pos, paste0("pos", name_detail, ".rds"))
write_rds(shots_ok, paste0("unblocked_shots", name_detail, ".rds"))
}
-
+
shots_ok
}
# shotsEN <- get_shots("data/events/events_England.json", "EN")
@@ -63,12 +63,12 @@ get_shots <- function(file_path, name_detail, save_files = F){
# shotsGE <- get_shots("data/events/events_Germany.json", "GE")
# shotsFR <- get_shots("data/events/events_France.json", "FR")
# shotsEC <- get_shots("data/events/events_European_Championship.json", "EC")
-#
+#
# shots <- shotsEN %>%
# bind_rows(shotsFR, shotsGE, shotsIT, shotsSP, shotsWC, shotsEC)
get_final_data <- function(data) {
-
+
data <- data %>% select(eventSec, y1, x1, is_goal, is_blocked, is_CA, body_part, foot)
data$x1 <- (100 - data$x1) * 105/100
data$y1 <- data$y1 * data$y1/100
@@ -77,7 +77,7 @@ get_final_data <- function(data) {
data <- data %>% mutate(distance = sqrt( (100 - x1)^2 + (34 - y1)^2),
minute = round(eventSec / 60),
eventSec = round(eventSec))
-
+
data
}
@@ -89,14 +89,14 @@ get_final_data <- function(data) {
get_data <- function(event_path, info_path) {
events <- read.csv(event_path)
info <- read.csv(info_path)
-
+
events <- merge(events, info[, c('id_odsp', 'country', 'date')], by = 'id_odsp', all.x = TRUE)
data <- subset(events, event_type == 1)
-
+
data_final <- data %>% select(sort_order, time, shot_place, shot_outcome, is_goal, location, bodypart, assist_method, situation,
fast_break)
data_final
-
+
}
# data2 <- get_data(event_path = "data/events.csv", info_path = "data/ginf.csv")
@@ -124,18 +124,18 @@ loc2locdistance <- function(x1, y1, x2, y2) {
get_shots2 <- function(json_file) {
data <- fromJSON(json_file) %>% filter(type$name == "Shot") %>% dplyr::select(c(minute, position, location, shot))
-
+
df_temp <- do.call(rbind, lapply(data$location, function(loc) c(120, 80) - loc))
colnames(df_temp) <- c("x1", "y1")
-
+
data$x1 <- df_temp[,1]
data$y1 <- df_temp[,2]
-
+
data$shot$freeze_frame <- Map(function(ff, x1, y1) {
ff$x1 <- yd_to_m(x1)
ff$y1 <- yd_to_m(y1)
return(ff)
- },
+ },
data$shot$freeze_frame, data$x1, data$y1)
tryCatch({
@@ -148,17 +148,17 @@ get_shots2 <- function(json_file) {
df <- df %>% mutate(teammate = ifelse(teammate, "teammate", "opponent"),
distance = loc2locdistance(x1 = x, y1 = y, x2 = x1, y2 = y1)) %>%
arrange(distance)
-
+
groups_count <- df %>% group_by(teammate) %>% count() %>% as.data.frame()
if ( !("opponent" %in% groups_count$teammate) ) {
groups_count <- groups_count %>% add_row(teammate = "opponent", n = 0)
} else if ( !("teammate" %in% groups_count$teammate) ) {
groups_count <- groups_count %>% add_row(teammate = "teammate", n = 0)
}
-
+
na_df <- as.data.frame(matrix("na", nrow = 21 - nrow(df), ncol = ncol(df)))
colnames(na_df) <- colnames(df)
-
+
na_df$teammate <- rep(c("opponent", "teammate"), c(11, 10) - groups_count$n)
dff <- rbind(df, na_df)
dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number(distance)) %>% ungroup() %>%
@@ -170,9 +170,9 @@ get_shots2 <- function(json_file) {
dff <- as.data.frame(matrix("na", nrow = 21, ncol = 3))
colnames(dff) <- c("x", "y", "teammate")
dff$teammate <- rep(c("opponent", "teammate"), c(11, 10))
- dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number()) %>% ungroup() %>%
- mutate(position_teammate = paste(teammate, rown, sep = "_")) %>%
- select(-c(teammate, rown)) %>%
+ dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number()) %>% ungroup() %>%
+ mutate(position_teammate = paste(teammate, rown, sep = "_")) %>%
+ select(-c(teammate, rown)) %>%
mutate(x = ifelse(x == "na", NA, x),
y = ifelse(x == "na", NA, y))
}
@@ -181,7 +181,7 @@ get_shots2 <- function(json_file) {
# %>%
# stop("123")
wider_df <- dff %>%
- pivot_wider(names_from = position_teammate, values_from = c(x, y), names_sep = "_player_") %>%
+ pivot_wider(names_from = position_teammate, values_from = c(x, y), names_sep = "_player_") %>%
mutate(across(everything(), as.numeric))
wider_df
# wider_df <- apply(wider_df, MARGIN = 2, unlist)
@@ -193,7 +193,7 @@ get_shots2 <- function(json_file) {
print(paste("An error occurred:", e$message))
})
df_players_location <- df_players_location %>% t()
-
+
tryCatch({ # TODO reduce error cases
data$number_of_players_opponents <- mapply(function(sublist, x1_threshold) {
# Extracting the first location value and converting it to numeric
@@ -213,12 +213,12 @@ get_shots2 <- function(json_file) {
# handle the error
print(paste("An error occurred:", e$message))
})
-
+
tryCatch({ # TODO reduce error cases
data$number_of_players_teammates <- mapply(function(sublist, x1_threshold) {
# Extracting the first location value and converting it to numeric
first_location_values <- sapply(sublist$location, function(loc) as.numeric(loc[1]))
-
+
if ("teammate" %in% names(sublist)) {
# Filtering and counting
res <- sum(sublist$teammate & first_location_values > x1_threshold) # error here
@@ -233,71 +233,71 @@ get_shots2 <- function(json_file) {
# handle the error
print(paste("An error occurred:", e$message))
})
-
-
+
+
data$shot <- data$shot %>% select(-freeze_frame, -statsbomb_xg, -key_pass_id)
data$shot$body_part <- data$shot$body_part %>% select(-id)
data$shot$technique <- data$shot$technique %>% select(-id)
data$shot$type <- data$shot$type %>% select(-id)
data$position <- data$position %>% select(-id)
-
+
data$shot <- data$shot %>% select(-end_location)
-
+
tryCatch({ # TODO reduce error cases
if ("one_on_one" %in% colnames(data$shot)) {
data[is.na(data$shot$one_on_one), ]$shot$one_on_one <- FALSE
} else {
data$shot$one_on_one <- FALSE
}
-
+
if ("first_time" %in% colnames(data$shot)) {
data[is.na(data$shot$first_time), ]$shot$first_time <- FALSE
} else {
data$shot$first_time <- FALSE
}
-
+
if ("aerial_won" %in% colnames(data$shot)) {
data[is.na(data$shot$aerial_won), ]$shot$aerial_won <- FALSE
} else {
data$shot$aerial_won <- FALSE
}
-
+
if ("saved_to_post" %in% colnames(data$shot)) {
data[is.na(data$shot$saved_to_post), ]$shot$saved_to_post <- FALSE
} else {
data$shot$saved_to_post <- FALSE
}
-
+
if ("deflected" %in% colnames(data$shot)) {
data[is.na(data$shot$deflected), ]$shot$deflected <- FALSE
} else {
data$shot$deflected <- FALSE
}
-
+
if ("saved_off_target" %in% colnames(data$shot)) {
data[is.na(data$shot$saved_off_target), ]$shot$saved_off_target <- FALSE
} else {
data$shot$saved_off_target <- FALSE
}
-
+
if ("open_goal" %in% colnames(data$shot)) {
data[is.na(data$shot$open_goal), ]$shot$open_goal <- FALSE
} else {
data$shot$open_goal <- FALSE
}
-
+
if ("follows_dribble" %in% colnames(data$shot)) {
data[is.na(data$shot$follows_dribble), ]$shot$follows_dribble <- FALSE
} else {
data$shot$follows_dribble <- FALSE
}
-
+
if ("redirect" %in% colnames(data$shot)) {
data[is.na(data$shot$redirect), ]$shot$redirect <- FALSE
} else {
data$shot$redirect <- FALSE
}
-
+
if ("kick_off" %in% colnames(data$kick_off)) {
data[is.na(data$shot$kick_off), ]$shotf$kick_off <- FALSE
} else {
@@ -308,21 +308,21 @@ get_shots2 <- function(json_file) {
# handle the error
print(paste("An error occurred:", e$message))
})
-
+
data <- data %>% mutate(is_goal = ifelse(shot$outcome$id == 97, 1, 0),
x1 = yd_to_m(x1) %>% round(., digits = 1),
y1 = yd_to_m(y1) %>% round(., digits = 1),
angle = loc2angle(x1, y1) %>% round(., digits = 1),
- distance = loc2distance(x = x1, y = y1)) %>%
+ distance = loc2distance(x = x1, y = y1)) %>%
select(-location)
data$shot$outcome <- data$shot$outcome %>% select(-id)
- data <- data %>% unnest(shot, names_sep = "_") %>%
- unnest(position, names_sep = "_") %>%
- unnest(shot_type, names_sep = "_") %>%
+ data <- data %>% unnest(shot, names_sep = "_") %>%
+ unnest(position, names_sep = "_") %>%
+ unnest(shot_type, names_sep = "_") %>%
unnest(shot_outcome, names_sep = "_") %>%
- unnest(shot_technique, names_sep = "_") %>%
+ unnest(shot_technique, names_sep = "_") %>%
unnest(shot_body_part, names_sep = "_")
-
+
data <- cbind(data, df_players_location)
data
}
@@ -338,12 +338,12 @@ skimr::skim(combined_data)
data3_final <- combined_data %>% select(-c(shot_outcome_name,
shot_saved_off_target,
shot_saved_to_post,
- kick_off)) %>%
+ kick_off)) %>%
mutate(shot_kick_off = ifelse(is.na(shot_kick_off), FALSE, shot_kick_off))
pattern <- "^(x_player_|y_player_).*$"
cols <- names(data3_final)[grepl(pattern, names(data3_final))]
data_final <- data3_final %>% unnest(all_of(cols))
skimr::skim(data_final)
write_csv(data_final, file = "data/final_data.csv")
-df_test <- read.csv("data/final_data.csv", nrows = 1000)
+#df_test <- read.csv("data/final_data.csv", nrows = 10000)
##################### The fourth dataset ##############################