{"cells":[{"metadata":{"_uuid":"cbe228463ab17127785ab3d158461ff93280e62c","_execution_state":"idle","trusted":true},"cell_type":"code","source":"# Loading Packages\nlibrary(tidyverse)\nlibrary(gridExtra)\nlibrary(ggplot2)\nlibrary(scales)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"ecb908c7b696db314d9402564c44074eb0eaa413"},"cell_type":"code","source":"# Check Data Files Available\nfile.info(list.files(path = \"../input\", full.names=TRUE))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6ff064c958d8139011deef9d3844061d3b120f82"},"cell_type":"code","source":"# Loading data except NGS data for now due to the large size\ngame_data <- read_csv(\"../input/game_data.csv\", guess_max = 20000)\nplay_info <- read_csv(\"../input/play_information.csv\", guess_max = 20000)\nplay_player_role <- read_csv(\"../input/play_player_role_data.csv\", guess_max = 20000)\nplayer_punt <- read_csv(\"../input/player_punt_data.csv\", guess_max = 20000)\nvideo_control <- read_csv(\"../input/video_footage-control.csv\", guess_max = 20000)\nvideo_injury <- read_csv(\"../input/video_footage-injury.csv\", guess_max = 20000)\nvideo_review <- read_csv(\"../input/video_review.csv\", guess_max = 20000)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c9d31c6fbce8ae080faf90b743a696c9317af18c"},"cell_type":"code","source":"# Check the video data\nhead(video_injury)\nhead(video_control)\nhead(video_review)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c6c9f1ff895c55c8695f99b84e63efefbce84ef6"},"cell_type":"code","source":"# Rename colnames for video_footage_control and injury data, add injury column, and merge them\nvideo_injury <- video_injury %>%\n  rename(Season_Year=season) %>%\n  rename(Season_Type=Type) %>%\n  rename(Home_Team=Home_team) %>%\n  rename(GameKey=gamekey) %>%\n  rename(PlayID=playid) %>%\n  rename(Preview_Link = `PREVIEW LINK (5000K)`) %>%\n  mutate(Injured=1)\n\nvideo_control <- video_control %>%\n  rename(Season_Year=season) %>%\n  rename(GameKey=gamekey) %>%\n  rename(Home_Team=Home_team) %>%\n  rename(PlayID=playid) %>%\n  rename(Preview_Link = `Preview Link`) %>%\n  mutate(Injured=0)\n\nvideo_combine <- rbind(video_injury, video_control)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2d6c88f8c578c771b50cd3588b54c988d365d82d"},"cell_type":"code","source":"# confirm if video_review and video_injury datasets are from the same plays in the same games\nvideo_injury_plays <- video_injury %>%\n  select(Season_Year, GameKey, PlayID) %>%\n  arrange(Season_Year, GameKey, PlayID)\n\nvideo_review_plays <- video_review %>%\n  select(Season_Year, GameKey, PlayID) %>%\n  arrange(Season_Year, GameKey, PlayID)\n\nall(video_review_plays == video_injury_plays)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f58be4ec2e68e9d7bb29882c83c86464b774ce75"},"cell_type":"markdown","source":"Video_review and video_injury are from the sample plays, it means that the plays in the video_injury are concussion-related injuries, not including other injuries."},{"metadata":{"trusted":true,"_uuid":"6615e33e31fc6fede3c65fd1ff6bfc7b5abf51d5"},"cell_type":"markdown","source":"Let's look at the combined injuried and non-injuried video data with game, play and player data"},{"metadata":{"trusted":true,"_uuid":"89dad6e45ac9d99d827bc367784fa9dc3823a5c1"},"cell_type":"code","source":"# Join game data with all injury and non-injury video data\npunt_plays <- video_combine %>%\n  left_join(game_data, by = c(\"Season_Year\", \"Season_Type\",\"Week\",\"GameKey\", \"Home_Team\", \"Visit_Team\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"424c3b257f13dcb59c9a7d1080046d36069f8a85"},"cell_type":"code","source":"# Function to get punt return team\nfind_return_team <- function(Poss_Team, Home_Team_Visit_Team){\n  home_team <- strsplit(Home_Team_Visit_Team, \"-\")[[1]][1]\n  visit_team <- strsplit(Home_Team_Visit_Team, \"-\")[[1]][2]\n  if (Poss_Team == home_team) {\n    temp <- visit_team\n  } else {\n    temp <- home_team\n  }\n  \n  return(temp)\n}\n\n# Function to calculate the yardline with respect to possession team\nPoss_YardLine <- function(Poss_Team, YardLine){\n  yard_team <- strsplit(YardLine, \" \")[[1]][1]\n  yard_number <- as.integer(strsplit(YardLine, \" \")[[1]][2])\n  \n  temp <- 0\n  if (yard_team == Poss_Team) {\n    temp <- yard_number\n  } else {\n    temp <- 100-yard_number\n  }\n  \n  return(temp)\n}\n\n# Function to calculate the score with respect to possession team\nPoss_Score <- function(Poss_Team, Home_Team_Visit_Team, Score){\n  home_score <- as.integer(strsplit(Score, \" - \")[[1]][1])\n  visit_score <- as.integer(strsplit(Score, \" - \")[[1]][2])\n  home_team <- strsplit(Home_Team_Visit_Team, \"-\")[[1]][1]\n  visit_team <- strsplit(Home_Team_Visit_Team, \"-\")[[1]][2]\n  \n  temp <- 0\n  if (home_team == Poss_Team) {\n    temp <- home_score-visit_score\n  } else {\n    temp <- visit_score-home_score\n  }\n  \n  return(temp)\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2b7070e1790b95a11a512bbc6a344ed019e6a249"},"cell_type":"code","source":"# Add Relative_YardLine and Relative_Score columns to play_info data and remove redundant columns\nplay_info_rm <- play_info %>%\n  rowwise() %>%\n  mutate(\n      Return_Team = find_return_team(Poss_Team, Home_Team_Visit_Team),\n      Relative_YardLine = Poss_YardLine(Poss_Team, YardLine),\n      Relative_Score = Poss_Score(Poss_Team, Home_Team_Visit_Team, Score_Home_Visiting)\n  ) %>%\n  select(-one_of(c(\"Game_Date\", \"Quarter\", \"PlayDescription\", \"Home_Team_Visit_Team\",  \"Score_Home_Visiting\",\"YardLine\", \"Play_Type\")))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"98d725d187ed5d23f9a09f6afd6b04012ce6e4d1"},"cell_type":"code","source":"# Join play_info data to video data\npunt_plays <- punt_plays %>%\n  left_join(play_info_rm, by = c(\"Season_Year\", \"Season_Type\", \"Week\", \"GameKey\", \"PlayID\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0c21c6e831628ff99999ceae59f7536556bbbad4"},"cell_type":"code","source":"# Function to assign player to punt coverage or punt return team depending on their roles\nfind_team <- function(role){\n  if (role %in% c(\"PDL2\", \"PDR3\",\"PLR2\",\n                  \"PLR\", \"PDR4\", \"VRi\",\n                  \"VRo\", \"VLo\", \"PDL3\",\n                  \"PLL\", \"PLL2\", \"PDR2\",\n                  \"PDL5\", \"PLM\", \"PR\",\n                  \"PDL4\", \"VL\", \"PDL1\",\n                  \"PDR1\", \"VLi\", \"PLR1\",\n                  \"VR\", \"PLL1\", \"PFB\",\n                  \"PDR5\", \"PDM\", \"PDL6\",\n                  \"PLL3\", \"PLR3\", \"PDR6\",\n                  \"PLM1\")) {\n    temp <- 0\n  } else if (role %in% c(\"PRG\", \"GR\", \"GL\",\n                         \"PLT\", \"PRT\", \"PLG\",\n                         \"PRW\", \"PLW\", \"P\",\n                         \"PPL\", \"PPR\", \"PPLi\",\n                         \"GLo\", \"PLS\", \"GRi\", \n                         \"GRo\", \"PPLo\", \"PC\",\n                         \"GLi\", \"PPRi\", \"PPRo\")) {\n    temp <- 1\n  } else {\n    temp <- NA\n  }\n  return(temp)\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0b53fc2f136797e321a65211f8b2cb71d1a13227","scrolled":true},"cell_type":"code","source":"# punt_play_punt_coverage_formation\npunt_play_punt_coverage_formation <- play_player_role %>%\n  rowwise() %>%\n  mutate(\n    Punting_Team = find_team(Role)\n  )  %>%\n  filter(Punting_Team == 1) %>%\n  arrange(Season_Year, GameKey, PlayID, Role) %>%\n  group_by(Season_Year, GameKey, PlayID) %>%\n  summarise(Punt_Coverage_Formation = paste(Role,collapse=','))\nlength(unique(punt_play_punt_coverage_formation$Punt_Coverage_Formation))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"83ddd7d43193dcb49f68eec667e8cc20349cd06f"},"cell_type":"code","source":"# punt_play_punt_return_formation\npunt_play_punt_return_formation <- play_player_role %>%\n  rowwise() %>%\n  mutate(\n    Punting_Team = find_team(Role)\n  )  %>%\n  filter(Punting_Team == 0) %>%\n  arrange(Season_Year, GameKey, PlayID, Role) %>%\n  group_by(Season_Year, GameKey, PlayID) %>%\n  summarise(Punt_Return_Formation = paste(Role,collapse=','))\nlength(unique(punt_play_punt_return_formation$Punt_Return_Formation))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e2ad42ac31ddd9c42ba03ecffadc258940fec030"},"cell_type":"markdown","source":"We can see in total there are 497 unique punt return play formations vs. 60 punt coverage play formations. Punt team tends to play more types of formation presumably in order to return the ball rather than fair catch."},{"metadata":{"trusted":true,"_uuid":"cb913ce925f027fcb682be8996e3187629846e10"},"cell_type":"code","source":"# Check punt player position data\n# There are players with different jersery numbers but same position. We will clean the data first with a focus on the position column\nplayer_punt_position <- player_punt %>%\n  group_by(GSISID) %>%\n  summarise(Player_Position = paste(unique(Position), collapse = ','))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6a80aaeffa18a636fe4edf478df3511e38f24b8d"},"cell_type":"code","source":"# Join the position data to player role data\nplay_player_position <- play_player_role %>%\n  left_join(player_punt_position, by = \"GSISID\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2b222e8e909354dc7abfe13879e657680b508eee"},"cell_type":"code","source":"# Similarly like role, we will put together different positions for punt coverage and punt return teams\npunt_play_punt_coverage_positions <- play_player_position %>%\n  rowwise() %>%\n  mutate(\n    Punting_Team = find_team(Role)\n  )  %>%\n  filter(Punting_Team == 1) %>%\n  arrange(Season_Year, GameKey, PlayID, Player_Position) %>%\n  group_by(Season_Year, GameKey, PlayID) %>%\n  summarise(Punt_Coverage_Positions = paste(Player_Position,collapse=','))\n\npunt_play_punt_return_positions <- play_player_position %>%\n  rowwise() %>%\n  mutate(\n    Punting_Team = find_team(Role)\n  )  %>%\n  filter(Punting_Team == 0) %>%\n  arrange(Season_Year, GameKey, PlayID, Player_Position) %>%\n  group_by(Season_Year, GameKey, PlayID) %>%\n  summarise(Punt_Return_Positions = paste(Player_Position,collapse=','))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e600a1f0159d21c2f4bd9049adffe230514422f4"},"cell_type":"code","source":"# Join role and position for punt coverage and punt return teams data to video data. Now we have a table containning risk and non-risk factors for both injury and non-injury punt plays.\npunt_plays_new <- punt_plays %>%\n  left_join(punt_play_punt_coverage_formation, by = c(\"Season_Year\", \"GameKey\", \"PlayID\")) %>%\n  left_join(punt_play_punt_return_formation, by = c(\"Season_Year\", \"GameKey\", \"PlayID\")) %>%\n  left_join(punt_play_punt_coverage_positions, by = c(\"Season_Year\", \"GameKey\", \"PlayID\")) %>%\n  left_join(punt_play_punt_return_positions, by = c(\"Season_Year\", \"GameKey\", \"PlayID\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8ac1ef277ebf7327d3330c2678cb14cecf602668"},"cell_type":"code","source":"# Let's plot injury and non-injury punt return plays vs different factors\ncolnames(punt_plays_new)\npunt_plays_new$Injured <- as.factor(punt_plays_new$Injured)\npunt_plays_new$Season_Year <- as.factor(punt_plays_new$Season_Year)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"eefd57107d46387a80bdf82258ada663bc315180"},"cell_type":"code","source":"# Response variable: Injured, should be 37 each.\nggplot(punt_plays_new, aes(x = Injured, fill = Injured)) +\n  geom_bar(stat='count') +\n  labs(x = 'injured and non-injured punt plays') +\n  geom_label(stat='count',aes(label=..count..), size=7) +\n  theme_grey(base_size = 18)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a29d62eaf201eadd37355d8c35e940f378fa6e50"},"cell_type":"markdown","source":"**Season Year**\n\nOf the 74 plays, all 37 non-injury plays are from 2017 season, 19 injury plays in 2016, and 18 in 2017. If the injury play data has a good representation of all injury plays, it seems that 2017 season has less number of injuries when actually more punt plays are played in 2017. This tells us that NFL have made positive changes to prevent less injuries in 2017."},{"metadata":{"trusted":true,"_uuid":"ee3aff22559a86f5b33cd588cbbf5bc1298a8ce1"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = Season_Year, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'season year') +\n  geom_label(stat='count', aes(label=..count..)) +\n  ggtitle(\"Number of Injury and Non-injury Punt Plays in Video Data by Season Year\")\n\nggplot(play_info, aes(x = as.factor(Season_Year))) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'season year') +\n  geom_label(stat='count', aes(label=..count..)) +\n  ggtitle(\"Number of Total Punt Plays by Season Year\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"aeef6d8dcf22b0e4a883d5b874efc144d648481a"},"cell_type":"markdown","source":""},{"metadata":{"_uuid":"6821c206345fb022b03657312d5221f6f2e46d01"},"cell_type":"markdown","source":"**Season Type**\n\nOf the 74 plays, all 37 non-injury plays are from regular season. For injury plays, 12 plays are from pre season and 25 are from regular season. No-post season injury plays. 32.4% of injury plays are from pre-season. However, pre-season plays are 21.9%, which tells us that there is higher risk for pre-season games."},{"metadata":{"trusted":true,"_uuid":"5cd57318e28b56f089de41c3d71fcbd2eb1634a5"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = Season_Type, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'season type') +\n  geom_label(stat='count', aes(label=..count..)) +\n  ggtitle(\"Number of Injury and Non-injury Punt Plays in Video Data by Season Type\")\n\nggplot(play_info, aes(x = as.factor(Season_Type))) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'season type') +\n  geom_label(stat='count', aes(label=..count..)) +\n  ggtitle(\"Number of Total Punt Plays by Season Type\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2af2703babff3a903249f659117716355710671c"},"cell_type":"markdown","source":"**Week**\n\nOf the 74 plays, all 37 non-injury plays are from week 2. For all injury plays, injuries occurred on lower and higher end, which means there could be more injuries at the early and late of one season. Looking at all the punt plays be week, it is surprsing to see the number of the punt plays played from week 1 to week 5 in the pre-season stage, which might explain why pre-season has higher chance of injuries. Given the steady distribution of number of punt plays after week 5, week 15 has a higher risk of injury."},{"metadata":{"trusted":true,"_uuid":"906dad814f854d04ac1b7e620c19f9c1b295c510"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = Week, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'game week') +\n  geom_label(stat='count', aes(label=..count..)) +\n  ggtitle(\"Number of Injury and Non-injury Punt Plays in Video Data by Week\")\n\nggplot(play_info, aes(x = Week)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'game week') +\n  geom_label(stat='count', aes(label=..count..)) +\n  ggtitle(\"Number of Total Punt Plays by Week\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"00fbac6cc66ba52e60dc06e6b4ac5cb47393d4d7"},"cell_type":"markdown","source":"**Team**\n\nFrom all the 37 injury plays, looking at the teams involved plot, the top 4 teams that are involved in injury plays are Tians (7), Redskins (5), Chiefs (5), Jaguars (5), and Panthers (5). "},{"metadata":{"trusted":true,"_uuid":"baf596ba772c1fb913840881366ccc3ebd08d4f1"},"cell_type":"code","source":"# home_team\nggplot(punt_plays_new, aes(x = Home_Team, fill = Injured)) +\n  geom_bar(stat='count', position='dodge') +\n  theme_grey() +\n  labs(x = 'home team') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays by Home Team\")\n\n# visit_team\nggplot(punt_plays_new, aes(x = Visit_Team, fill = Injured)) +\n  geom_bar(stat='count', position='dodge') +\n  theme_grey() +\n  labs(x = 'visit team') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays by Visit Team\")\n\n# any team\nvisit_team_plays <- punt_plays_new %>%\n    select(-one_of(\"Home_Team\")) %>%\n    rename(Team=Visit_Team)\n\nhome_team_plays <- punt_plays_new %>%\n    select(-one_of(\"Visit_Team\")) %>%\n    rename(Team=Home_Team)\n\ntotal_team_plays <- rbind(home_team_plays, visit_team_plays)\n\nggplot(total_team_plays, aes(x = Team, fill = Injured)) +\n  geom_bar(stat='count', position='dodge') +\n  theme_grey() +\n  labs(x = 'teams involved') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip() +\n  ggtitle(\"Number of Injury and Non-injury Punt Plays by Team\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6832d5347edeea5528b90bb643be114b659ad8cf"},"cell_type":"markdown","source":"Let's also look at all the punt plays by team played.  As mentioned earlier, Tians (7), Redskins (5), Chiefs (5), Jaguars (5), and Panthers (5) are more likely be involved in injury plays. Is that because there are more punt plays for them? JAX was involved in the most number of punt plays, 494 out of 6681 total plays. Same as Chiefs. Interstingly Titans and Redskins did not have that much 208 and 186."},{"metadata":{"trusted":true,"_uuid":"79289ace00d3519a171185ca6ea6c7fb4470bf6b"},"cell_type":"code","source":"play_info_team <- play_info %>%\n  rowwise() %>%\n  mutate(\n      Home_Team = strsplit(Home_Team_Visit_Team, split='-')[[1]][1],\n      Visit_Team = strsplit(Home_Team_Visit_Team, split='-')[[1]][2],\n      Return_Team = find_return_team(Poss_Team, Home_Team_Visit_Team),\n      Relative_YardLine = Poss_YardLine(Poss_Team, YardLine),\n      Relative_Score = Poss_Score(Poss_Team, Home_Team_Visit_Team, Score_Home_Visiting)\n  )\n\n# home_team\nggplot(play_info_team, aes(x = Home_Team)) +\n  geom_bar(stat='count', position='dodge') +\n  theme_grey() +\n  labs(x = 'home team') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Total Punt Plays by Home Team\")\n\n# visit_team\nggplot(play_info_team, aes(x = Visit_Team)) +\n  geom_bar(stat='count', position='dodge') +\n  theme_grey() +\n  labs(x = 'visit team') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Total Punt Plays by Visit Team\")\n\n# any team\nplay_info_visit_team <- play_info_team %>%\n    select(-one_of(\"Home_Team\")) %>%\n    rename(Team=Visit_Team)\n\nplay_info_home_team <- play_info_team %>%\n    select(-one_of(\"Visit_Team\")) %>%\n    rename(Team=Home_Team)\n\nplay_info_total_team <- rbind(play_info_home_team, play_info_visit_team)\n\nggplot(play_info_total_team, aes(x = Team)) +\n  geom_bar(stat='count', position='dodge') +\n  theme_grey() +\n  labs(x = 'teams involved') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip() +\n  ggtitle(\"Number of Total Punt Plays by Team\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"91060f3b514beabee4b21a6bbc9c08f2b013e3a1"},"cell_type":"markdown","source":"**Punt Coverage and Punt Return Team**\n\nFrom the possession team, Tians tends to have more injuries when they are punting. Surprisingly that Blatimore Raves and Denver Broncos tend to cause injuries when they are returning punt."},{"metadata":{"trusted":true,"_uuid":"6f66cb82ba7cb323acf3f0afc623886b196eda55"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = Poss_Team, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  facet_wrap(\"Injured\")+\n  labs(x = 'possession team') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays in by Punting Team\")\n\nggplot(play_info_team, aes(x = Poss_Team)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'possession team') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Total Plays by Punting Team\")\n\nggplot(punt_plays_new, aes(x = Return_Team, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  facet_wrap(\"Injured\")+\n  labs(x = 'return team') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays in by Returning Team\")\n\nggplot(play_info_team, aes(x = Return_Team)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'return team') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Total Plays by Returning Team\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d08dcf02d5bca8e6b6c989c1db2ccc1b98b2104f"},"cell_type":"markdown","source":"**Quarter**\n\nFor the 37 control plays, there are more 1st half punt plays than 2nd half during the game. For the 37 injury plays, injuries seem occur more in the 2nd and 3rd quaters. If we compare this number with all the punt plays, we can see that 2nd quarter is responsible for the most number of plays. But 3rd quarter punt plays have much higher chance of injury rising from 23.8% to 37.8% assuming each punt play has a chance of injury. In addition, there are no quarter 5 or over time injuries even though there are punt plays in over time.\n\n"},{"metadata":{"trusted":true,"_uuid":"c8911eed0425faf5e7718d1c4366da67c947b347"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = Qtr, fill = Injured)) +\n  geom_bar(stat='count', position='dodge') +\n  theme_grey() +\n  labs(x = 'Quarter') +\n  geom_label(stat='count', aes(label=..count..))+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays in Video Data by Quarter\")\n\nggplot(play_info, aes(x = as.factor(Quarter))) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'season year') +\n  geom_label(stat='count', aes(label=..count..)) +\n  ggtitle(\"Number of Total Punt Plays by Quarter\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"793a8c6916345cdfa3a375244c8d7051641ef843"},"cell_type":"markdown","source":"**Game_Date**\n\nAll 37 control plays are from a short period time in 2017 seaon. Of 37 injury plays, they seem distributed uniformly across the season months."},{"metadata":{"trusted":true,"_uuid":"1ccbee9967fcbf435f71fa1874abd3b6d6c16560"},"cell_type":"code","source":"punt_plays_new$Game_Date_2 <- as.Date(format(punt_plays_new$Game_Date, \"%m/%d\"), \"%m/%d\")\nggplot(punt_plays_new, aes(x = Game_Date_2, fill = Injured)) +\n  geom_bar(stat='count', position='dodge') +\n  theme_grey() +\n  labs(x = 'game date') +\n  ggtitle(\"Number of Injury and Non-injury Punt Plays in Video Data by Date\")+\n  scale_x_date(labels = date_format(\"%m\"))\n\nplay_info$Game_Date_2 <- as.Date(format(as.Date(play_info$Game_Date, format=\"%m/%d/%Y\"), \"%m/%d\"), \"%m/%d\")\nggplot(play_info, aes(x = Game_Date_2)) +\n  geom_bar(stat='count', position='dodge') +\n  theme_grey() +\n  labs(x = 'game date') +\n  ggtitle(\"Number of Total Plays in Video Data by Date\") +\n  scale_x_date(labels = date_format(\"%m\"))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9658f3c1334b257fa010e14caf7d445da5a81c39"},"cell_type":"markdown","source":"**Game_Site**\n\nThis is a facor that is more critical than home_team, as injuries can happen due to the game site field condition. The top 4 are Landover (4), Nashville (3), Kansas City (3), East Rutherford (3). Those four game sites corresponding to the home filed of Redskins, Titans, Chiefs, and Giants/Jets. Giants and Jets are two teams that share the same statium. This information could be missed if only looking at the plays by team. It also shows the high risk of those four game sites causing injury either from the site condition or home team players. In addition, comparing with the teams involved data, even though Jaguars and Pathers correspond to more injury plays. However, it is probably not becuase the game site played as the Jaguars home field is at Jacksonville (1) and Panthers is at Charlotte (1). It is more likely that those two teams are associated with higher risk of injury, either been injured or causing injury.\n\nFrom the total punt plays at different sites, we can see that other than oversee sites or special game sites, each site almost are playing similar amounts of the punt plays. As a result, Landover does have more injury plays than other sites."},{"metadata":{"trusted":true,"_uuid":"152caf4d614b5fcf01462582a214bb32b120bc75"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = Game_Site, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'game site') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip() +\n  ggtitle(\"Number of Injury and Non-injury Punt Plays in Video Data by Game Site\")\n\n# join play info with game data\nplay_info_game <- play_info %>%\n  left_join(game_data, by = c(\"Season_Year\", \"Season_Type\",\"Week\",\"GameKey\"))\n\nggplot(play_info_game, aes(x = Game_Site)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'game site') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip() +\n  ggtitle(\"Number of Total Punt Plays by Game Site\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b395b27c0530a64ee0d6ca7a7cf5f6fd1f12fe3b"},"cell_type":"markdown","source":"**Start_Time**\n\nThe distriubtion of cases for injury plays depending the game start time seems correlate with the games played in NFL for afternoon and night games with a slightly higher possibility for night games as usually only three games played each week at night in the regular season with the remaining games in the afternoon. However, they are significant number of injuries happend for games played after 7pm in particually after 7:45pm. And games played during the daytime tend to have less injuries."},{"metadata":{"trusted":true,"_uuid":"efdb9f3ebedb7c194141c8dfc4e76919b4702ad7"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = Start_Time, fill = Injured)) +\n  geom_bar(stat='count', position='dodge') +\n  theme_grey() +\n  labs(x = 'start time') +\n  geom_label(stat='count', aes(label=..count..))+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays in Video Data by Start Time\")\n\nggplot(play_info_game, aes(x = Start_Time)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'game site') +\n  geom_label(stat='count', aes(label=..count..))+\n  ggtitle(\"Number of Total Punt Plays by Start Time\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1aa16a901f70f1b0699534dd9b170ea557e7270d"},"cell_type":"markdown","source":"**Stadium**\n\nThis provides the same information as game_site. Not that MetLift Statidum and MetLife should be the same stadium."},{"metadata":{"trusted":true,"_uuid":"be7ed699ce42af48ef5f1e4ed4208b3e8830b7f1"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = Stadium, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'stadium') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip() +\n  ggtitle(\"Number of Injury and Non-injury Punt Plays by Stadium\")\n\nggplot(play_info_game, aes(x = Stadium)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'stadium') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Total Punt Plays by Stadium\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"def913df51a39f801e8b4affabeb85afd5603ccd"},"cell_type":"markdown","source":"**StadiumType**\n\nOutdoor games tend to have higher risk of injury. 28 out of 37 (75.7%) plays for injury plays are outdoor games. For the total punt plays, 4473 out of 6681 (67%) are outdoor plays. Outdoor game tends to have slightly higher chance of injuries."},{"metadata":{"trusted":true,"_uuid":"ac088cdf64e8ada6fc572a6e70ec70a1057de4d4"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = StadiumType, fill = Injured)) +\n  geom_bar(stat='count', position='dodge') +\n  theme_grey() +\n  labs(x = 'stadium type') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays in Video Data by Stadium Type\")\n\nggplot(play_info_game, aes(x = StadiumType)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'stadium') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Total Punt Plays by Stadium Type\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"709a88d4a9d47e7f5620984aa2088680da89e4b5"},"cell_type":"markdown","source":"**Turf**\n\nThe vaules of Turf type are a little messy and I am not sure of the differencs betweeen Natural Grass and Grass, and those two are popular turf type.."},{"metadata":{"trusted":true,"_uuid":"7e8edd8a7a0a5fc63a37a5208ff0699456b4c908"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = Turf, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'turf') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip() +\n  ggtitle(\"Number of Injury and Non-injury Punt Plays by Turf\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7b77f16dbb48a84b9fafa52d5711e32a8bad9cf5"},"cell_type":"markdown","source":"**GameWeather**\n\nThe main two descriptions for game weather are sunny and cloudy, and those two seem to contribute equally for injury plays."},{"metadata":{"trusted":true,"_uuid":"ef630cd9b836b299804c032da302d3f61521b33e"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = GameWeather, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'game weather') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip() +\n  ggtitle(\"Number of Injury and Non-injury Punt Plays in Video Data by Game Weather\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7965f99cdae5ba64a627ae7540a04daa8e2993f6"},"cell_type":"markdown","source":"**Temperature**\n\nIf we group the temperature into ranges, we can find that most punt plays are played in the range of 60+. It is obviously that low tempertuare correspond to higher risk of injury if we compare to the percentage of plays played at the range of 30-40 F. Same as <30F condition."},{"metadata":{"trusted":true,"_uuid":"f145374f91e20e07d4c838f9aec8f539454aa4d3"},"cell_type":"code","source":"punt_plays_new$temperature_range <- cut(as.numeric(punt_plays_new$Temperature),breaks = c(-Inf, 30,40, 50, 60, 70, 80, Inf), labels=c(\"0-30\", \"30-40\", \"40-50\", \"50-60\", \"60-70\", \"70-80\", \"80+\"))\nggplot(punt_plays_new, aes(x = temperature_range, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  facet_wrap(\"Injured\")+\n  labs(x = 'game temperature') +\n  geom_label(stat='count', aes(label=..count..))+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays in Video Data by Temperature\")\n\nplay_info_game$temperature_range <- cut(as.numeric(play_info_game$Temperature),breaks = c(-Inf, 30,40, 50, 60, 70, 80, Inf), labels=c(\"0-30\", \"30-40\", \"40-50\", \"50-60\", \"60-70\", \"70-80\", \"80+\"))\nggplot(play_info_game, aes(x = temperature_range)) +\n  geom_bar(stat='count') +\n  theme_grey()+\n  labs(x = 'game temperature') +\n  geom_label(stat='count', aes(label=..count..))+\n  ggtitle(\"Number of Total Plays in Video Data by Temperature\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d69494f9f32b6bbce46e29672f5477118ba45dcf"},"cell_type":"markdown","source":"**Game_Clock**\n\nGame clock data supposes to give insights into when the injury is likely to occur in a quarter. When game clock is lower than 6 minutes, there is an increased risk of injury."},{"metadata":{"trusted":true,"_uuid":"3f49413ff333fb5bbcf3ac09d5ea498fa2eadccc"},"cell_type":"code","source":"punt_plays_new$clock_range <- cut(as.numeric(punt_plays_new$Game_Clock),breaks = c(0, 10800, 21600, 32400, 43200, 54000), labels=c(\"0-3\", \"3-6\", \"6-9\", \"9-12\", \"12+\"))\n\nggplot(punt_plays_new, aes(x = clock_range, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  facet_wrap(\"Injured\")+\n  labs(x = 'game clock (mins)') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays by Game Clock\")\n\nplay_info_game$clock_range <- cut(as.numeric(play_info_game$Game_Clock),breaks = c(0, 10800, 21600, 32400, 43200, 54000), labels=c(\"0-3\", \"3-6\", \"6-9\", \"9-12\", \"12+\"))\n\nggplot(play_info_game, aes(x = clock_range)) +\n  geom_bar(stat='count') +\n  theme_grey()+\n  labs(x = 'game clock (mins)') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Total Punt Plays by Game Clock\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0b2e7262329572537b73c01e786c3d935053c32a"},"cell_type":"markdown","source":"**Yard Line**\n\nThis is an interest factor which could affect punt plays. For all 2016 and 2017 games, most punt plays are played at yard line 20-30 (24.6%). However, for all injury plays, the ratio of 20-30 yard line has a significantly higher chance of injury (45.9%). This tells us that if a punt play is played at 20-30 yard line, the possibility of injury increased from 24.6% to 45.9%, almost doubled, assuming for each punt play there will be injury."},{"metadata":{"trusted":true,"_uuid":"9a731c18f6bd06349e8c79a2dd5ea28d96386f25"},"cell_type":"code","source":"punt_plays_new$yardline_range <- cut(punt_plays_new$Relative_YardLine,breaks = c(0, 10, 20, 30, 40, 50, 100), labels=c(\"0-10\", \"10-20\", \"20-30\", \"30-40\", \"40-50\",\"50+\"))\n\nggplot(punt_plays_new, aes(x = yardline_range, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  facet_wrap(\"Injured\")+\n  labs(x = 'yard line away from possession team endzone') +\n  geom_label(stat='count', aes(label=..count..))+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays by Relative Yard Line\")\n\n\nplay_info_rm$yardline_range <- cut(play_info_rm$Relative_YardLine,breaks = c(0, 10, 20, 30, 40, 50, 100), labels=c(\"0-10\", \"10-20\", \"20-30\", \"30-40\", \"40-50\",\"50+\"))\n\nggplot(play_info_rm, aes(x = yardline_range)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'yard line away from possession team endzone') +\n  geom_label(stat='count', aes(label=..count..))+\n  ggtitle(\"Number of Total Punt Plays by Relative Yard Line\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f75076d9167cecb087c7221fdff24f4efbd9d624"},"cell_type":"markdown","source":"**Score**\n\nBy comparing the distribution of relative score difference by possession team, we can find that when puntting team are leading within 7 points, or one poessesstion game, the chance of injury rises. If punting team is falling behind by 7 points, it is considered to be much safer."},{"metadata":{"trusted":true,"_uuid":"ff0ca56fe5de1f4112094eec5107fba3cc0716d1"},"cell_type":"code","source":"punt_plays_new$score_range <- cut(punt_plays_new$Relative_Score,breaks = c(-Inf, -14, -7, 0, 7, 14, Inf), labels=c(\"-14+\", \"-14~-7\", \"-7~0\", \"0~7\", \"7~14\",\"14+\"))\n\nggplot(punt_plays_new, aes(x = score_range, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  facet_wrap(\"Injured\")+\n  labs(x = 'score difference of possession team') +\n  geom_label(stat='count', aes(label=..count..))+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays by Relative Score\")\n\nplay_info_rm$score_range <- cut(play_info_rm$Relative_Score,breaks = c(-Inf, -14, -7, 0, 7, 14, Inf), labels=c(\"-14+\", \"-14~-7\", \"-7~0\", \"0~7\", \"7~14\",\"14+\"))\n\nggplot(play_info_rm, aes(x = score_range)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'score difference of possession team') +\n  geom_label(stat='count', aes(label=..count..))+\n  ggtitle(\"Number of Total Punt Plays by Relative Score\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c9c816b5a906c598524bf5ba0fd340fac4c14fd2"},"cell_type":"markdown","source":"**Punt Coverage Team Formation**\n\nPunt coverage team formation is very standard, including only two main cases, for injury plays. \"GL,GR,P,PLG,PLS,PLT,PLW,PPR,PRG,PRT,PRW\" formation corresponding to much higher chance of injury comparing to \"GL,GR,P,PLG,PLS,PLT,PLW,PPL,PRG,PRT,PRW\". If we compare the punt coverage formation in detail. We can find one difference maker player is either PPR or PPL, corresponding to the punt player pretector either standing on the right or left. The pretector stands on the right correspond to 70% of the injuries.\n\nLet's look at all the 2016 and 2017 season plays. \"GL,GR,P,PLG,PLS,PLT,PLW,PPR,PRG,PRT,PRW\" and \"GL,GR,P,PLG,PLS,PLT,PLW,PPL,PRG,PRT,PRW\" indeed are the two major formations for punt coverage with PPR plays nearly (60%) and PPL (40%). This makes sense due to the same reason as most people are right handed. However, PPR formation did cause the injury rate up from 60% to 70% with 10% increase."},{"metadata":{"trusted":true,"_uuid":"8a113ff36ed3baaa02e06f054cdd2d5142a34b17"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = Punt_Coverage_Formation, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  facet_wrap(\"Injured\")+\n  labs(x = 'punt coverage team formation') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays by Punt Team Formation\")\n\nggplot(punt_play_punt_coverage_formation, aes(x = Punt_Coverage_Formation)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'punt coverage team formation') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Total Punt Plays by Punt Team Formation\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b089978f3a97f8ed4b5578163c40d412e4eaf60f"},"cell_type":"markdown","source":"**Punt Return Team Formation**\n\nThree major formations are adopted in punt return injury plays: \"PDL1,PDL2,PDL3,PDR1,PDR2,PLL,PR,VLi,VLo,VRi,VRo\", \"PDL1,PDL2,PDL3,PDR1,PDR2, PDR3,PR,VLi,VLo,VRi,VRo\", and \"PDL1,PDL2,PDL3,PDR1,PDR2,PDR3,PLL,PLR,PR,VL,VR\". In comparison, all the plays it is also ture that three formations are used dominantly, which are \"PDL1,PDL2,PDL3,PDR1,PDR2,PDR3,PLL,PLR,PR,VL,VR\", \"PDL1,PDL2,PDL3,PDL4,PDR1,PDR2,PDR3,PDR4,PR,VL,VR\", \"PDL1,PDL2,PDL3,PDR1,PDR2,PDR3,PR,VLi,VLo,VRi,VRo\". We can see that the most popular formation \"PDL1,PDL2,PDL3,PDR1,PDR2,PDR3,PLL,PLR,PR,VL,VR\" (9%) and third most popular formation \"PDL1,PDL2,PDL3,PDR1,PDR2,PDR3,PR,VLi,VLo,VRi,VRo\" (8.6%) are associated with high risk of injury. The 2nd most popular formation is also associated with injury. Howeve, the formation \"PDL1,PDL2,PDL3,PDR1,PDR2,PLL,PR,VLi,VLo,VRi,VRo\" corresponds to 1.2% of plays, but has high risk of injury, which should be avoided. Other four punt return formaitons with injuries (5.4%) are \"PDL1,PDL2,PDL3,PDL4,PDR1,PDR2,PDR3,PDR4,PR,VL,VR\", \"PDL1,PDL2,PDL3,PDR1,PDR2,PDR3,PLL,PR,VLi,VLo,VR\", \"PDL1,PDL2,PDR1,PDR2,PDR3,PLM,PR,VLi,VLo,VRi,VRo\", and \"PDL1,PDL2,PDR1,PDR2,PDR3,PLR,PR,VLi,VLo,VRi,VRo\" are played 9%, 2.2%, 0.8% and 1% of all plays.\n\nIn conclusion, three formations \"PDL1,PDL2,PDR1,PDR2,PDR3,PLM,PR,VLi,VLo,VRi,VRo\",  \"PDL1,PDL2,PDR1,PDR2,PDR3,PLR,PR,VLi,VLo,VRi,VRo\" and \"PDL1,PDL2,PDL3,PDR1,PDR2,PLL,PR,VLi,VLo,VRi,VRo\" are all used less frequently <1.2% but correspond to higher injury risk. All those three formations use VLi, VLo, VRi, VRo, in other words, four players outside the number in the field to take away GL or GR from punt coverage teams."},{"metadata":{"trusted":true,"_uuid":"da865b5b8abc676c28ed496165acdc5a9293b092"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = Punt_Return_Formation, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  facet_wrap(\"Injured\")+\n  labs(x = 'punt return team formation') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays by Return Team Formation\")\n\nggplot(punt_play_punt_return_formation, aes(x = Punt_Return_Formation)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'punt return team formation') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Total Punt Plays by Return Team Formation\")\n\npunt_return_formation_percent_injury <- punt_plays_new %>%\n    filter(Injured==1)%>%\n    group_by(Punt_Return_Formation) %>%\n    summarise(number = n()) %>%\n    mutate(percent=number/sum(number))%>%\n    arrange(desc(number))\n\npunt_return_formation_percent_all <- punt_play_punt_return_formation %>%\n    group_by(Punt_Return_Formation) %>%\n    summarise(number = n()) %>%\n    mutate(percent=number/sum(number))%>%\n    arrange(desc(number))\n\npunt_return_formation_percent_injury %>%\n    left_join(punt_return_formation_percent_all, by=\"Punt_Return_Formation\")\npunt_return_formation_percent_all","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d9de5a73a3619552ac3db8c0e96cb719f1a8574b"},"cell_type":"markdown","source":""},{"metadata":{"trusted":true,"_uuid":"ded779f752396378f33aba8c496bcad3c37d247b"},"cell_type":"markdown","source":"**Punt Coverage Team Positions**\n\nI did not find any correlation so far."},{"metadata":{"trusted":true,"_uuid":"a678adcd42b1dc54996b6d9581fc74943294ec20"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = Punt_Coverage_Positions, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  facet_wrap(\"Injured\")+\n  labs(x = 'punt coverage team player positions') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays by Punt Team Positions\")\n\nggplot(punt_play_punt_coverage_positions, aes(x = Punt_Coverage_Positions)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'punt coverage team player positions') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Total Punt Plays by Punt Team Positions\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"505d77be67fdff1e63098237c828b7d9607e7b59"},"cell_type":"code","source":"punt_coverage_positions_percent_injury <- punt_plays_new %>%\n    filter(Injured==1)%>%\n    group_by(Punt_Coverage_Positions) %>%\n    summarise(number = n()) %>%\n    mutate(percent=number/sum(number))%>%\n    arrange(desc(number))\n\npunt_coverage_positions_percent_all <- punt_play_punt_coverage_positions %>%\n    group_by(Punt_Coverage_Positions) %>%\n    summarise(number = n()) %>%\n    mutate(percent=number/sum(number))%>%\n    arrange(desc(number))\n\npunt_coverage_positions_percent_injury %>%\n    left_join(punt_coverage_positions_percent_all, by=\"Punt_Coverage_Positions\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"434518d3ca402cbc49c329748fc102797cd415c8"},"cell_type":"markdown","source":"**Punt Return Team Positions**\n\nTwo of the most adopted team positions used are \"CB,CB,CB,FB,ILB,ILB,OLB,RB,SS,WR,WR\" and \"CB,CB,FB,ILB,ILB,OLB,RB,SS,SS,WR,WR\". But in the injury plays the two highest injury rate team positions are different, which are \"CB,CB,CB,CB,FS,ILB,ILB,OLB,TE,TE,WR\" and \"CB,FB,FS,ILB,ILB,RB,RB,RB,TE,WR,WR\". We can see that in the two injury palys, one case uses 4CB and 1FS, 2TEs, 1WR, another case uses 3RBs, 1TE, 2WRs in additions to the typical 3CBs, RB/SS, SS, 2WRs. The more useage of CB, FS, and RB are likely to cause injury, probably becuare they are more atheletic players and more volunable to injuries as well in the play."},{"metadata":{"trusted":true,"_uuid":"dcc2599245739ed81b09fdea01b932862d41d37d"},"cell_type":"code","source":"ggplot(punt_plays_new, aes(x = Punt_Return_Positions, fill = Injured)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  facet_wrap(\"Injured\")+\n  labs(x = 'punt return team player positions') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Injury and Non-injury Punt Plays by Return Team Positions\")\n\nggplot(punt_play_punt_return_positions, aes(x = Punt_Return_Positions)) +\n  geom_bar(stat='count') +\n  theme_grey() +\n  labs(x = 'punt return team player positions') +\n  geom_label(stat='count', aes(label=..count..))+\n  coord_flip()+\n  ggtitle(\"Number of Total Punt Plays by Return Team Positions\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"32f4bc77a2242a3cfee1ee8cf8a38f0947b11e3f"},"cell_type":"code","source":"punt_return_positions_percent_injury <- punt_plays_new %>%\n    filter(Injured==1)%>%\n    group_by(Punt_Return_Positions) %>%\n    summarise(number = n()) %>%\n    mutate(percent=number/sum(number))%>%\n    arrange(desc(number))\n\npunt_return_positions_percent_all <- punt_play_punt_return_positions %>%\n    group_by(Punt_Return_Positions) %>%\n    summarise(number = n()) %>%\n    mutate(percent=number/sum(number))%>%\n    arrange(desc(number))\n\npunt_return_positions_percent_injury %>%\n    left_join(punt_return_positions_percent_all, by=\"Punt_Return_Positions\")\npunt_return_positions_percent_all","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2a6eb97e939914ecf42e562ae4c957312804607f"},"cell_type":"markdown","source":"OK. We looked at a lots of factors so far including game or play related. But we haven't look at the NGS data, which are more critical. Becuase they provide insights into the movement of player in the field including speed, acceleration and direction as a function of time. They could also give us clear picture how collisions result in injury. As I mentioned earlier, the size of NGS data is very large. I will give an example how the analysis is done before aggregating all the data. I picked an injury play where the play description is the longest, in the hoping that might be of interest (Season_Year 2016, GameKey 274, PlayID 3609)."},{"metadata":{"trusted":true,"_uuid":"51d91a6f84fdf9412d81eb3713055c43c6fb6544"},"cell_type":"code","source":"# Load NGS data with play of interest Season_Year 2016, GameKey 274, PlayID 3609\nNGS_Data_interest <- read_csv(\"../input/NGS-2016-reg-wk13-17.csv\", guess_max = 20000)\nhead(NGS_Data_interest)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"35f736b42d607bec9cc8517ca85fad305343179b"},"cell_type":"code","source":"NGS_Data_interest <- NGS_Data_interest %>%\n    filter(Season_Year == 2016, GameKey == 274, PlayID == 3609) %>%\n    arrange(Time)\nhead(NGS_Data_interest)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"db3969a9ef4149505f0976c7eb476b98b3bf37a7"},"cell_type":"markdown","source":"Play description is (5:22) (Punt formation) J.Ryan up the middle to LA 47 for 26 yards. FUMBLES, recovered by SEA-N.Thorpe at LA 40. SEA-J.Ryan was injured during the play. Los Angeles challenged the loose ball recovery ruling, and the play was Upheld. The ruling on the field stands. (Timeout #2.) We can find more about this game in the game and play information data. This play was played between Seattle Seahawsk and Los Angeles Rams on season 2016 week 15. Seattle Seahawks is the home team. The play was played at Seattle 27 YardLine. Seattle was leading by 24-3. Accroding to the injury analysis provided by video review data, injured player 23742 was tackled by player 31785 by helmet-to-helmet."},{"metadata":{"trusted":true,"_uuid":"1ef2a65626fe166f5ea3762d48cc68bc05d4210b"},"cell_type":"code","source":"# injury description by video review\nvideo_review %>%\n    filter(Season_Year == 2016, GameKey == 274, PlayID == 3609)\n\n# play information\nplay_info %>%\n    filter(Season_Year == 2016, GameKey == 274, PlayID == 3609)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6dba08ece38ca93745ca0ca83b5a71b6c8379612"},"cell_type":"markdown","source":"Let's look at the NGS data of these two players. It is a punt fake play where player 1 started running from left to the opponent enzone with a direction towards lower right. Player 2 figured out the fake punt play and shifted himselft back towards the upper right and tackled player 1 at about 61 yards. I also calculated their speed and acceleration."},{"metadata":{"_uuid":"30ee60cf8238fe20acd73e2a97f07c19efccd8ce","trusted":true},"cell_type":"code","source":"# Injured player 23742\nNGS_Data_interest_P1 <- NGS_Data_interest %>%\n  filter(GSISID == 23742) %>%\n  arrange(Time) %>%\n  mutate(pre_Time = lag(Time, n = 1)) %>%\n  mutate(dt = ifelse(is.na(Time-pre_Time), 0.1, Time-pre_Time)) %>%\n  mutate(s = round(dis/as.numeric(dt), 2)) %>%\n  mutate(pre_s = lag(s, n=1)) %>%\n  mutate(ds = ifelse(is.na(s-pre_s), 0, s-pre_s)) %>%\n  mutate(a = round(ds/as.numeric(dt), 2)) %>%\n  mutate(pre_o = lag(o, n = 1),\n         pre_dir = lag(dir, n = 1)) %>%\n  mutate(s_o = ifelse(is.na(o-pre_o), 0, round((o-pre_o)/as.numeric(dt), 2)),\n         s_dir= ifelse(is.na(dir-pre_dir), 0, round((dir-pre_dir)/as.numeric(dt), 2))) %>%\n  select(-one_of(c(\"pre_Time\", \"pre_s\", \"ds\", \"pre_o\", \"pre_dir\")))\n\n# Partner player 31785\nNGS_Data_interest_P2 <- NGS_Data_interest %>%\n  filter(GSISID == 31785) %>%\n  arrange(Time) %>%\n  mutate(pre_Time = lag(Time, n = 1)) %>%\n  mutate(dt = ifelse(is.na(Time-pre_Time), 0.1, Time-pre_Time)) %>%\n  mutate(s = round(dis/as.numeric(dt), 2)) %>%\n  mutate(pre_s = lag(s, n=1)) %>%\n  mutate(ds = ifelse(is.na(s-pre_s), 0, s-pre_s)) %>%\n  mutate(a = round(ds/as.numeric(dt), 2)) %>%\n  mutate(pre_o = lag(o, n = 1),\n         pre_dir = lag(dir, n = 1)) %>%\n  mutate(s_o = ifelse(is.na(o-pre_o), 0, round((o-pre_o)/as.numeric(dt), 2)),\n         s_dir= ifelse(is.na(dir-pre_dir), 0, round((dir-pre_dir)/as.numeric(dt), 2))) %>%\n  select(-one_of(c(\"pre_Time\", \"pre_s\", \"ds\", \"pre_o\", \"pre_dir\"))) \n\n# Merge two table and calculate their distance over time\nNGS_Data_interest_join <- inner_join(\n  NGS_Data_interest_P1, NGS_Data_interest_P2, by = c(\"Season_Year\",\"GameKey\",\"PlayID\",\"Time\")\n) %>%\n  mutate(\n    distance = sqrt((x.x-x.y)^2 + (y.x-y.y)^2),\n    Relative_Time = Time-NGS_Data_interest_P1$Time[1]\n  )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cc4c7d26518b0c9d8f83d7fa88b247d155ced328"},"cell_type":"code","source":"ggplot(NGS_Data_interest_join, aes(x=x.x, y=y.x, shape = as.factor(GSISID.x))) + \n  geom_point(color = 'red') + \n  labs (x = 'x direction (yards)', y = 'y direction (yards)') +\n  geom_point(aes(x=x.y, y=y.y, shape = as.factor(GSISID.y))) +\n  theme(legend.position = 'top', legend.title = element_blank()) +\n  annotate(geom = 'text', x=NGS_Data_interest_join$x.x[1], y=NGS_Data_interest_join$y.x[1], label = 'P1 Start') +\n  annotate(geom = 'text', x=NGS_Data_interest_join$x.y[1], y=NGS_Data_interest_join$y.y[1], label = 'P2 Start') +\n  geom_rect(aes(xmin = 0, xmax = 10,\n                ymin = 0, ymax = 53.3),\n            color = \"palegreen1\", alpha = 0) +\n  geom_rect(aes(xmin = 110, xmax = 120,\n                ymin = 0, ymax = 53.3),\n            color = \"palegreen1\", alpha = 0) +\n  geom_rect(aes(xmin = 0, xmax = 120,\n                ymin = 0, ymax = 53.3),\n            color = \"black\", alpha = 0) +\n  coord_fixed(ratio=53.5/120) +\n  scale_x_continuous(breaks=c(10,20,30,40,50,60,70,80,90,100,110), labels=c(0,10,20,30,40,50,60,70,80,90,100))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e0e9e3e144a96fc4dc6f06cb4f7b69b0dbbdcb8f"},"cell_type":"markdown","source":"If we plot their distance as a function of time, we can see that in this play their distance reaches a minum when the tackled is made. The game flow states punt_play, line_set, ball_snap, punt_fake, run, fumble, fumble_offense_recoved, tackle, and play_submit."},{"metadata":{"trusted":true,"_uuid":"2595b69a027c012c8fe7fdd213183a5c63bef661"},"cell_type":"code","source":"ggplot(NGS_Data_interest_join, aes(x=Relative_Time, y=distance)) +\n  geom_line() +\n  geom_text(aes(label=Event.x), angle=45, vjust=0, hjust=0) +\n  geom_point(data=subset(NGS_Data_interest_join, !is.na(Event.x)), aes(x=Relative_Time, y=distance), color='red')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"64e211f6d16952710a87fea968d960cfb2950604"},"cell_type":"markdown","source":"If we plot both players' speed and acceleration as a function of time, we can see that player 23742 kept his full speed about 8 yards/second and his speed dropped over a short amount of the time after being tackled. This can also be seen in the acceleartion plot that his acceleration decreased from 0 to -15 after tackle. While for 31785 his speed was much faster, nearly 9 yards per second although he deacceleated to -20 after making the tackle."},{"metadata":{"trusted":true,"_uuid":"e6a63c6a2cb6ce19f92b2c60ed9c40b4acc3f224"},"cell_type":"code","source":"# GSISID player 23742 speed yard per second\nggplot(NGS_Data_interest_join, aes(x=Relative_Time, y=s.x)) +\n  geom_line() +\n  geom_text(aes(label=Event.x), angle=45, vjust=0, hjust=0) +\n  geom_point(data=subset(NGS_Data_interest_join, !is.na(Event.x)), aes(x=Relative_Time, y=s.x), color='red')\n\n# GSISID player 23742 acceleration yard per second2\nggplot(NGS_Data_interest_join, aes(x=Relative_Time, y=a.x)) +\n  geom_line() +\n  geom_text(aes(label=Event.x), angle=45, vjust=0, hjust=0) +\n  geom_point(data=subset(NGS_Data_interest_join, !is.na(Event.x)), aes(x=Relative_Time, y=a.x), color='red')\n\n# GSISID player 31785 speed yard per second\nggplot(NGS_Data_interest_join, aes(x=Relative_Time, y=s.y)) +\n  geom_line() +\n  geom_text(aes(label=Event.x), angle=45, vjust=0, hjust=0) +\n  geom_point(data=subset(NGS_Data_interest_join, !is.na(Event.x)), aes(x=Relative_Time, y=s.y), color='red')\n\n# GSISID player 31785 acceleration yard per second2\nggplot(NGS_Data_interest_join, aes(x=Relative_Time, y=a.y)) +\n  geom_line() +\n  geom_text(aes(label=Event.x), angle=45, vjust=0, hjust=0) +\n  geom_point(data=subset(NGS_Data_interest_join, !is.na(Event.x)), aes(x=Relative_Time, y=a.y), color='red')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"06c8c6f619e7107ca3fb62a9ce2b7905dcc83f27"},"cell_type":"markdown","source":"The player position and distance data is very straightforward. Let's look at the orientation and direction of these two players. I already mentioned above that Seattle is the Home Team and Rams is the visiting team. Seahaws punter (#23742) is moving towards lower right and Rams player (#31785) is moving towards top right when the impact occurred.\n\n**From the GSISID player 23742 orientation plot, the player maintained approximately 10 degree orientation before the injury. His direction kept at constant 100 degree from ball_snap to tackle. However, based on coordination system and increasing direction provided in the drawing by the competition organizer. The angle the player is facing should be around 260 degree and the direction he is running should be 260 degree as well since he is running straight in a linear fashion. I got confused by the orientation and direction angle data provided and decide to use these two factors very carefully in the following studies. Same with GSISID player 31785, according to the plot from NGS data the palyer kept about 300 degree orientation and 50 degree direction when he attempted his tackling. But based on the drawing his oritentaion and direction should be different angle. The only explanation I could give is that the drawing could be wrong but it is just my guess. I adjusted the coordination system and 0 degree starting direction in a scheme from my presentation slide and is available upon request. Bascially for orientation, 0 degree should be pointing to the visitor team endzone (or Rams endzone in this case) with a clockwise direction for increasing. Under this assumption, 23742 player's orientation then would be 10 degree and 31785's orientation would be 300 degree. While for direction, 0 degree should be pointing up to visitor sideline with a clockwise direction for increasing. Under this assumption, 23742 player's direction then would be 100 degree and 31785's direction would be 50 degree. The orientation and direction data would only make sense after the correction I mentioned here.**"},{"metadata":{"trusted":true,"_uuid":"ba08233a81c8859bb1c19b6e3e983af5b66c8b60"},"cell_type":"code","source":"# GSISID player 23742 orientation\nggplot(NGS_Data_interest_join, aes(x=Relative_Time, y=o.x)) +\n  geom_line() +\n  geom_text(aes(label=Event.x), angle=45, vjust=0, hjust=0) +\n  geom_point(data=subset(NGS_Data_interest_join, !is.na(Event.x)), aes(x=Relative_Time, y=o.x), color='red')\n\n# GSISID player 23742 direction\nggplot(NGS_Data_interest_join, aes(x=Relative_Time, y=dir.x)) +\n  geom_line() +\n  geom_text(aes(label=Event.x), angle=45, vjust=0, hjust=0) +\n  geom_point(data=subset(NGS_Data_interest_join, !is.na(Event.x)), aes(x=Relative_Time, y=dir.x), color='red')\n\n# GSISID player 31785 orientation\nggplot(NGS_Data_interest_join, aes(x=Relative_Time, y=o.y)) +\n  geom_line() +\n  geom_text(aes(label=Event.x), angle=45, vjust=0, hjust=0) +\n  geom_point(data=subset(NGS_Data_interest_join, !is.na(Event.x)), aes(x=Relative_Time, y=o.y), color='red')\n\n# GSISID player 31785 direction\nggplot(NGS_Data_interest_join, aes(x=Relative_Time, y=dir.y)) +\n  geom_line() +\n  geom_text(aes(label=Event.x), angle=45, vjust=0, hjust=0) +\n  geom_point(data=subset(NGS_Data_interest_join, !is.na(Event.x)), aes(x=Relative_Time, y=dir.y), color='red')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"be38c36187871d9188b5abf0a3b777a0aefc063b"},"cell_type":"markdown","source":"OK. Now let's load all NGS data provided in particular for control and injury plays."},{"metadata":{"trusted":true,"_uuid":"bdffd2122b6d0d21f80012c02d6cbca9751857bb"},"cell_type":"code","source":"# function to load NGS data from csv files and merge with plays of interest\nNGS_video_plays <- function(plays_interest, NGS_file_path) {\n  NGS_data <- read_csv(NGS_file_path, guess_max = 20000)\n  temp <- inner_join(plays_interest, NGS_data, by=c(\"Season_Year\", \"GameKey\", \"PlayID\"))\n  return(temp)\n}\n\n# Extract punt plays in videos from NGS\npunt_plays_interest <- punt_plays %>%\n  select(Season_Year, GameKey, PlayID)\n\npunt_plays_NGS <- data.frame()\npunt_plays_NGS <- NGS_video_plays(punt_plays_interest, \"../input/NGS-2016-pre.csv\")\npunt_plays_NGS <- rbind(punt_plays_NGS, NGS_video_plays(punt_plays_interest, \"../input/NGS-2016-reg-wk1-6.csv\"))\npunt_plays_NGS <- rbind(punt_plays_NGS, NGS_video_plays(punt_plays_interest, \"../input/NGS-2016-reg-wk7-12.csv\"))\npunt_plays_NGS <- rbind(punt_plays_NGS, NGS_video_plays(punt_plays_interest, \"../input/NGS-2016-reg-wk13-17.csv\"))\npunt_plays_NGS <- rbind(punt_plays_NGS, NGS_video_plays(punt_plays_interest, \"../input/NGS-2016-post.csv\"))\npunt_plays_NGS <- rbind(punt_plays_NGS, NGS_video_plays(punt_plays_interest, \"../input/NGS-2017-pre.csv\"))\npunt_plays_NGS <- rbind(punt_plays_NGS, NGS_video_plays(punt_plays_interest, \"../input/NGS-2017-reg-wk1-6.csv\"))\npunt_plays_NGS <- rbind(punt_plays_NGS, NGS_video_plays(punt_plays_interest, \"../input/NGS-2017-reg-wk7-12.csv\"))\npunt_plays_NGS <- rbind(punt_plays_NGS, NGS_video_plays(punt_plays_interest, \"../input/NGS-2017-reg-wk13-17.csv\"))\npunt_plays_NGS <- rbind(punt_plays_NGS, NGS_video_plays(punt_plays_interest, \"../input/NGS-2017-post.csv\"))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5143e60f697955cb74a5f86039c50e74d53c7b30"},"cell_type":"code","source":"# function to explore any two palyers within one play for collisions\nfind_collision <- function(data, year, gamekey, playid, id1, id2){\n  \n  # player 1\n  P1 <- data %>%\n    filter(Season_Year == year, GameKey == gamekey, PlayID == playid, GSISID == id1) %>%\n    arrange(Time) %>%\n    mutate(pre_Time = lag(Time, n = 1)) %>%\n    mutate(dt = ifelse(is.na(Time-pre_Time), 0.1, Time-pre_Time)) %>%\n    mutate(s = round(dis/as.numeric(dt), 2)) %>%\n    mutate(pre_s = lag(s, n=1)) %>%\n    mutate(ds = ifelse(is.na(s-pre_s), 0, s-pre_s)) %>%\n    mutate(a = round(ds/as.numeric(dt), 2)) %>%\n    mutate(pre_o = lag(o, n = 1),\n           pre_dir = lag(dir, n = 1)) %>%\n    mutate(s_o = ifelse(is.na(o-pre_o), 0, round((o-pre_o)/as.numeric(dt), 2)),\n           s_dir= ifelse(is.na(dir-pre_dir), 0, round((dir-pre_dir)/as.numeric(dt), 2))) %>%\n    select(-one_of(c(\"pre_Time\", \"pre_s\", \"ds\", \"pre_o\", \"pre_dir\")))\n  \n  # player 2\n  P2 <- data %>%\n    filter(Season_Year == year, GameKey == gamekey, PlayID == playid, GSISID == id2) %>%\n    arrange(Time) %>%\n    mutate(pre_Time = lag(Time, n = 1)) %>%\n    mutate(dt = ifelse(is.na(Time-pre_Time), 0.1, Time-pre_Time)) %>%\n    mutate(s = round(dis/as.numeric(dt), 2)) %>%\n    mutate(pre_s = lag(s, n=1)) %>%\n    mutate(ds = ifelse(is.na(s-pre_s), 0, s-pre_s)) %>%\n    mutate(a = round(ds/as.numeric(dt), 2)) %>%\n    mutate(pre_o = lag(o, n = 1),\n           pre_dir = lag(dir, n = 1)) %>%\n    mutate(s_o = ifelse(is.na(o-pre_o), 0, round((o-pre_o)/as.numeric(dt), 2)),\n           s_dir= ifelse(is.na(dir-pre_dir), 0, round((dir-pre_dir)/as.numeric(dt), 2))) %>%\n    select(-one_of(c(\"pre_Time\", \"pre_s\", \"ds\", \"pre_o\", \"pre_dir\"))) \n  \n  # Merge two table and calculate their distance over time\n  interest_join <- inner_join(P1, P2, by = c(\"Season_Year\",\"GameKey\",\"PlayID\",\"Time\")) %>%\n    mutate(\n      distance = sqrt((x.x-x.y)^2 + (y.x-y.y)^2),\n      Relative_Time = Time-P1$Time[1]\n    )\n  \n  return(interest_join)\n}\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c8f1e111c152ffe06de54cdfdb4b7ee4b991b7b8"},"cell_type":"code","source":"test <- find_collision(punt_plays_NGS, 2017, 601, 602, 33260, 31697)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"29131f11c481512b367615b38c0f629c03214fe8"},"cell_type":"code","source":"ggplot(test, aes(x=x.x, y=y.x, shape = as.factor(GSISID.x))) + \n  geom_point(color = 'red') + \n  labs (x = 'x direction (yards)', y = 'y direction (yards)') +\n  geom_point(aes(x=x.y, y=y.y, shape = as.factor(GSISID.y))) +\n  theme(legend.position = 'top', legend.title = element_blank()) +\n  annotate(geom = 'text', x=test$x.x[1], y=test$y.x[1], label = 'P1 Start') +\n  annotate(geom = 'text', x=test$x.y[1], y=test$y.y[1], label = 'P2 Start') +\n  geom_rect(aes(xmin = 0, xmax = 10,\n                ymin = 0, ymax = 53.3),\n            color = \"palegreen1\", alpha = 0) +\n  geom_rect(aes(xmin = 110, xmax = 120,\n                ymin = 0, ymax = 53.3),\n            color = \"palegreen1\", alpha = 0) +\n  geom_rect(aes(xmin = 0, xmax = 120,\n                ymin = 0, ymax = 53.3),\n            color = \"black\", alpha = 0) +\n  coord_fixed(ratio=53.5/120) +\n  scale_x_continuous(breaks=c(10,20,30,40,50,60,70,80,90,100,110), labels=c(0,10,20,30,40,50,60,70,80,90,100))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0b2aeb664d0d19a416e89a3de6fbb3274c2e1127"},"cell_type":"code","source":"# GSISID player 23742 orientation\nggplot(test, aes(x=Relative_Time, y=o.x)) +\n  geom_line() +\n  geom_text(aes(label=Event.x), angle=45, vjust=0, hjust=0) +\n  geom_point(data=subset(test, !is.na(Event.x)), aes(x=Relative_Time, y=o.x), color='red')\n\n# GSISID player 23742 direction\nggplot(test, aes(x=Relative_Time, y=dir.x)) +\n  geom_line() +\n  geom_text(aes(label=Event.x), angle=45, vjust=0, hjust=0) +\n  geom_point(data=subset(test, !is.na(Event.x)), aes(x=Relative_Time, y=dir.x), color='red')\n\n# GSISID player 31785 orientation\nggplot(test, aes(x=Relative_Time, y=o.y)) +\n  geom_line() +\n  geom_text(aes(label=Event.x), angle=45, vjust=0, hjust=0) +\n  geom_point(data=subset(test, !is.na(Event.x)), aes(x=Relative_Time, y=o.y), color='red')\n\n# GSISID player 31785 direction\nggplot(test, aes(x=Relative_Time, y=dir.y)) +\n  geom_line() +\n  geom_text(aes(label=Event.x), angle=45, vjust=0, hjust=0) +\n  geom_point(data=subset(test, !is.na(Event.x)), aes(x=Relative_Time, y=dir.y), color='red')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ee73ac9ce39039535ecb754d4044891d6c5c3c72"},"cell_type":"markdown","source":"Future plans include visualizing the player location, speed, acceleration, direction and face angle when collision occurred, which should give more insights into the actual injury how tackle or block is made. NGS data can also be visulized for comparing game time."},{"metadata":{"_uuid":"8e7ea3394ca7a3e902f63fe0b7bfc4b785a3f4fe"},"cell_type":"markdown","source":""},{"metadata":{"_uuid":"6aeb3e5281270f6e6de052668b0d7dcdf1683101"},"cell_type":"markdown","source":""},{"metadata":{"_uuid":"25ae9ac5478e984495de3fa11edd5da63817758f"},"cell_type":"markdown","source":""},{"metadata":{"_uuid":"c2435090818cb0b0a753061a60de9f49115e1eb2"},"cell_type":"markdown","source":""}],"metadata":{"kernelspec":{"display_name":"R","language":"R","name":"ir"},"language_info":{"mimetype":"text/x-r-source","name":"R","pygments_lexer":"r","version":"3.4.2","file_extension":".r","codemirror_mode":"r"}},"nbformat":4,"nbformat_minor":1}