{"metadata":{"kernelspec":{"name":"ir","display_name":"R","language":"R"},"language_info":{"name":"R","codemirror_mode":"r","pygments_lexer":"r","mimetype":"text/x-r-source","file_extension":".r","version":"4.0.5"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"#library\nlibrary(readr)\nlibrary(tidyverse)\nlibrary(ggplot2)\nlibrary(stargazer)\nlibrary(lessR)\nlibrary(gtsummary)\nlibrary(lubridate)\nlibrary(ggalluvial)\nlibrary(psych)\nlibrary(olsrr)\nlibrary(MASS)\nlibrary(dplyr)","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:17:05.623061Z","iopub.execute_input":"2022-01-05T16:17:05.625090Z","iopub.status.idle":"2022-01-05T16:17:09.185498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import datasets\ngames <- read_csv(\"../input/nfl-big-data-bowl-2022/games.csv\")\nPFFScoutingData <- read_csv(\"../input/nfl-big-data-bowl-2022/PFFScoutingData.csv\")\nplayers <- read_csv(\"../input/nfl-big-data-bowl-2022/players.csv\")\nplays <- read_csv(\"../input/nfl-big-data-bowl-2022/plays.csv\")\ntracking2018 <- read_csv(\"../input/nfl-big-data-bowl-2022/tracking2018.csv\")\ntracking2019 <- read_csv(\"../input/nfl-big-data-bowl-2022/tracking2019.csv\")\ntracking2020 <- read_csv(\"../input/nfl-big-data-bowl-2022/tracking2020.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:17:48.800645Z","iopub.execute_input":"2022-01-05T16:17:48.842148Z","iopub.status.idle":"2022-01-05T16:18:20.016259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"game_play_data <- merge(games,plays,by=\"gameId\")","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:18:23.142212Z","iopub.execute_input":"2022-01-05T16:18:23.143872Z","iopub.status.idle":"2022-01-05T16:18:23.201960Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"kickoff_total <- game_play_data %>% filter(specialTeamsPlayType == \"Kickoff\")\n\n\n# adjust datatype\nkickoff_total$homeTeamAbbr <- as.factor(kickoff_total$homeTeamAbbr)\nkickoff_total$visitorTeamAbbr <- as.factor(kickoff_total$visitorTeamAbbr)\nkickoff_total$possessionTeam <- as.factor(kickoff_total$possessionTeam)\nkickoff_total$specialTeamsPlayType <- as.factor(kickoff_total$specialTeamsPlayType)\nkickoff_total$specialTeamsResult <- as.factor(kickoff_total$specialTeamsResult)\nkickoff_total$penaltyCodes <- as.factor(kickoff_total$penaltyCodes)\nkickoff_total$yardlineSide <- as.factor(kickoff_total$yardlineSide)\n\nsummary(kickoff_total)","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:18:27.307371Z","iopub.execute_input":"2022-01-05T16:18:27.309286Z","iopub.status.idle":"2022-01-05T16:18:27.678206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# subset only \"good\" and \"bad\" teams from plays\nkickoff_totalgood <- kickoff_total %>% \n  filter(possessionTeam == \"KC\" & season == \"2018\"| possessionTeam == \"NO\" & season == \"2018\"|\n           possessionTeam == \"BAL\"& season == \"2019\"| possessionTeam == \"SF\"& season == \"2019\"|\n           possessionTeam == \"KC\"& season == \"2020\"| possessionTeam == \"GB\"& season == \"2020\")\n\nkickoff_totalbad <-  kickoff_total %>% \n  filter(possessionTeam == \"ARI\" & season == \"2018\"| possessionTeam == \"OAK\" & season == \"2018\"|\n           possessionTeam == \"CIN\" & season == \"2019\"| possessionTeam == \"WAS\" & season == \"2019\"|\n           possessionTeam == \"JAX\" & season == \"2020\"| possessionTeam == \"ATL\" & season == \"2020\")\n\nkickoff_totalgood <- kickoff_totalgood %>% add_column(goodorbad=\"Good\")\nkickoff_totalbad <- kickoff_totalbad %>% add_column(goodorbad=\"Bad\")\nkickoff_total_data <- rbind(kickoff_totalgood,kickoff_totalbad)\nkickoff_total_data$goodorbad <- as.factor(kickoff_total_data$goodorbad)\nkickoff_total_data <- kickoff_total_data %>% filter(specialTeamsResult!=\"Non-Special Teams Result\")\n\n","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:18:36.302495Z","iopub.execute_input":"2022-01-05T16:18:36.304084Z","iopub.status.idle":"2022-01-05T16:18:36.487473Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BarChart(specialTeamsResult,data=kickoff_totalbad,main=\"Bad teams' special team result of kickoffs\")\n#less \"Return\" specialTeamResult in good team than bad team.","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:18:48.619423Z","iopub.execute_input":"2022-01-05T16:18:48.621210Z","iopub.status.idle":"2022-01-05T16:18:48.834734Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BarChart(specialTeamsResult,data=kickoff_totalgood,main=\"Good teams' special team result of kickoffs\")","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:18:52.460900Z","iopub.execute_input":"2022-01-05T16:18:52.462679Z","iopub.status.idle":"2022-01-05T16:18:52.512045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Downed, Fair Catch: Similar for good and bad teams;\n\nReturn: Bad teams > Good teams;\n\nOut of Bounds: Bad teams > Good teams\n\nTouchback : Good team > Bad team\n\nOut of bounds: Bad team < Good team\n\nTouchback and Return are the most frequent occurrences for both good and bad teams","metadata":{}},{"cell_type":"code","source":"# distribution of playResult with respect to different special team results\nggplot(kickoff_totalgood,aes(specialTeamsResult,playResult)) +\n  geom_boxplot()+\n  ggtitle(\"Good teams\")\n  \n\nggplot(kickoff_totalbad,aes(specialTeamsResult,playResult)) +\n  geom_boxplot()+\n  ggtitle(\"Bad teams\")\n","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:18:56.411757Z","iopub.execute_input":"2022-01-05T16:18:56.413476Z","iopub.status.idle":"2022-01-05T16:18:57.103760Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Muffed has the best playresult. It means that the possesion team may change to kickoff teams or after the muffed the return team be forced to move to their endzone to protect their possesion. \nThe playresult of return is better than fair catch,which is similar to the SpecialTeamsPlayTeam. It means that althrough the kick return team by choosing fair catch can not advance in this play, they have already win some yards compare to by return without mistakes,it maybe be caused by the shorter kicklength.\nThe most frequent SpecialteamResult \"Touchback\" and \"Return\" have very close playresults,but \"Return\" is a little better for both bad and good teams. ","metadata":{}},{"cell_type":"code","source":"boxplot(kickoff_totalgood$kickLength,kickoff_totalbad$kickLength, col=c(\"red\",\"blue\"),xlab =\"kick length of kickoff by Good Teams (red) vs Bad Team (blue)\")","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:19:01.403029Z","iopub.execute_input":"2022-01-05T16:19:01.404628Z","iopub.status.idle":"2022-01-05T16:19:01.492371Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The kicklength of good team is longer than the bad team. And the bad teams have some shorter kicklengths as outliers. \nWe assume that one of the good things the good team do,is the larger kicklength.","metadata":{}},{"cell_type":"code","source":"boxplot(kickoff_totalgood$kickReturnYardage,kickoff_totalbad$kickReturnYardage, col=c(\"red\",\"blue\"),xlab =\"kickReturnYardage of kickoff by Good Teams (red) vs Bad Team (blue)\")","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:19:10.994277Z","iopub.execute_input":"2022-01-05T16:19:10.995827Z","iopub.status.idle":"2022-01-05T16:19:11.076598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"To verify this assumption,we turn to the most common results \"Return\" and \"TouchBack\".Having 228 times \"Return\" as the specialTeamRessult,the good teams face to more \"Return\" than bad team, although this is not a large percentage for themselves. And a larger kicklength can not bring a good playresult directly, because their opposing team also make a larger \"kickReturnYardage\". The \"kickReturnYardage\" may recovery some kicklength. So,weather the larger kicklength is good strategy due to the playresult.","metadata":{}},{"cell_type":"code","source":"kickoff_dataPFF <- merge(kickoff_total_data, PFFScoutingData,by=c(\"gameId\",\"playId\"))\nkickoff_dataPFF %>% filter(specialTeamsResult == \"Touchback\"|\n                               specialTeamsResult == \"Return\") %>% \n  ggplot(aes(hangTime, kickLength, col=specialTeamsResult)) +\n  geom_point()","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:19:17.213356Z","iopub.execute_input":"2022-01-05T16:19:17.215036Z","iopub.status.idle":"2022-01-05T16:19:17.643427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"As we see, with the same hangTime, larger kicklengths will be more likely to result in touchback.From the previous plotS the playresult of \"Return\" is better than \"Touchback\".So, the team should control the kicklength, if they want to avoid Touchback. From the previous plot, the good team have larger kicklength, so their strategy is not to avoid touchback, it may due to the unsignificant difference between the results of \"Return\" and \"TouchBack\". Or control the kicklength may have some the negative effect.","metadata":{}},{"cell_type":"code","source":"kicklengthEffect_dataPFF <- merge(kickoff_total_data, PFFScoutingData,by=c(\"gameId\",\"playId\"))\nkicklengthEffect_dataPFF %>% filter(specialTeamsResult == \"Muffed\"|\n                               specialTeamsResult == \"Out of Bounds\"|\n                                   specialTeamsResult == \"Kickoff Team Recovery\"|\n                                   specialTeamsResult == \"Fair Catch\"|\n                                   specialTeamsResult == \"Downed\") %>% \n  ggplot(aes(hangTime, kickLength, col=specialTeamsResult)) +\n  geom_point()","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:19:34.237808Z","iopub.execute_input":"2022-01-05T16:19:34.239516Z","iopub.status.idle":"2022-01-05T16:19:34.632365Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The larger kicklength ","metadata":{}},{"cell_type":"markdown","source":"This shows that a longer Kicklength leads to Touchback as well as Muffed, which is a very good result because the playResult of Muffed is significantly better than that of Touchback and Return. The shorter kicklength leads to Return as well as Fair Catch and Out of Bounds, which are bad result because the playResult of Fair Catch and out of bounds are significantly worse than that of Touchback and Return. \n\n**** The good team choose a rational strategy during kickoff: kick the ball further. They ignore the insignficant difference of playResult between Touchback and Return. They kick further to avoid the out of bounds, fair catch. Moreover,a larger kicklength has possibility of muffed, which gives the pressure to return team protect their possesion.","metadata":{}},{"cell_type":"code","source":"tracking2018 <- read_csv(\"../input/nfl-big-data-bowl-2022/tracking2018.csv\")\ntracking2019 <- read_csv(\"../input/nfl-big-data-bowl-2022/tracking2019.csv\")\ntracking2020 <- read_csv(\"../input/nfl-big-data-bowl-2022/tracking2020.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:19:39.816969Z","iopub.execute_input":"2022-01-05T16:19:39.818443Z","iopub.status.idle":"2022-01-05T16:19:56.717178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# The observed observation of Muffed is too less(Good Team: 1 observation, Bad Team: 4 observations).\n# So, to analysis the data of muffed, The data of all teams will be considered.\nKickoffMuffed <- game_play_data %>% filter(specialTeamsPlayType == \"Kickoff\" & specialTeamsResult == \"Muffed\")\n","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:25:00.410650Z","iopub.execute_input":"2022-01-05T16:25:00.413208Z","iopub.status.idle":"2022-01-05T16:25:00.452691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"KickoffMuffed_PFF <- merge(KickoffMuffed, PFFScoutingData,by=c(\"gameId\",\"playId\"))\nKickoffMuffed2018 <- merge(KickoffMuffed_PFF,tracking2018, by=c(\"gameId\",\"playId\"))\nKickoffMuffed2019 <- merge(KickoffMuffed_PFF,tracking2019, by=c(\"gameId\",\"playId\"))\nKickoffMuffed2020 <- merge(KickoffMuffed_PFF,tracking2020, by=c(\"gameId\",\"playId\"))","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:25:05.293521Z","iopub.execute_input":"2022-01-05T16:25:05.295186Z","iopub.status.idle":"2022-01-05T16:27:07.511167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"KickoffMuffed_temp = rbind(KickoffMuffed2018, KickoffMuffed2019)\nKickoffMuffed_total = rbind(KickoffMuffed_temp, KickoffMuffed2020)\nsummary(KickoffMuffed_total)","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:28:19.901633Z","iopub.execute_input":"2022-01-05T16:28:19.903225Z","iopub.status.idle":"2022-01-05T16:28:25.735543Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"KickoffMuffed_Total = KickoffMuffed_total %>% \n  mutate(kickType = as.factor(kickType),\n         kickDirectionIntended = as.factor(kickDirectionIntended),\n         kickDirectionActual = as.factor(kickDirectionActual),\n         playDirection  = as.factor(playDirection))","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:28:31.571385Z","iopub.execute_input":"2022-01-05T16:28:31.573123Z","iopub.status.idle":"2022-01-05T16:28:31.616228Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ggplot(KickoffMuffed_Total,aes(kickType)) +\n  geom_bar()\nBarChart(kickType,data= KickoffMuffed_Total,main=\"kickType of kickoffs and result in Muffed\")","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:28:35.349177Z","iopub.execute_input":"2022-01-05T16:28:35.350659Z","iopub.status.idle":"2022-01-05T16:28:35.732696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"KickoffNegativ <- game_play_data %>% filter(specialTeamsPlayType == \"Kickoff\" )%>%\n filter(specialTeamsResult == \"Out of bounds\"|specialTeamsResult == \"Fair Catch\")\nKickoffNegativ_PFF <- merge(KickoffNegativ, PFFScoutingData,by=c(\"gameId\",\"playId\"))\nKickoffNegativ2018 <- merge(KickoffNegativ_PFF,tracking2018, by=c(\"gameId\",\"playId\"))\nKickoffNegativ2019 <- merge(KickoffNegativ_PFF,tracking2019, by=c(\"gameId\",\"playId\"))\nKickoffNegativ2020 <- merge(KickoffNegativ_PFF,tracking2020, by=c(\"gameId\",\"playId\"))\nKickoffNegativ_temp = rbind(KickoffNegativ2018, KickoffNegativ2019)\nKickoffNegativ_total = rbind(KickoffNegativ_temp, KickoffNegativ2020)\nsummary(KickoffNegativ_total)","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:28:40.364671Z","iopub.execute_input":"2022-01-05T16:28:40.366296Z","iopub.status.idle":"2022-01-05T16:30:39.890744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BarChart(kickType,data= KickoffNegativ_total,main=\"kickType of kickoffs and result in Muffed\")\n","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:31:21.930844Z","iopub.execute_input":"2022-01-05T16:31:21.932486Z","iopub.status.idle":"2022-01-05T16:31:21.978378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"With comparing the kickType of the positive result \"Muffed\" with kickType of the negative result \"Out of Bounds\" and \"Fair Catch\", the kickTypes are totally different. All kicks result in negative result belong to Pooch kick - high for hangtime but not a lot of distance. The Muffed usually have a Deep Kick - your normal deep kick with decent hang time.","metadata":{}},{"cell_type":"code","source":"KickoffGB_Total_PFF <- merge(kickoff_total_data,PFFScoutingData, by=c(\"gameId\",\"playId\"))\nKickoffGB_Total2018 <- merge(KickoffGB_Total_PFF,tracking2018, by=c(\"gameId\",\"playId\"))\nKickoffGB_Total2019 <- merge(KickoffGB_Total_PFF,tracking2019, by=c(\"gameId\",\"playId\"))\nKickoffGB_Total2020 <- merge(KickoffGB_Total_PFF,tracking2020, by=c(\"gameId\",\"playId\"))\nKickoffGB_Total_temp = rbind(KickoffGB_Total2018, KickoffGB_Total2019)\nKickoffGB_Total = rbind(KickoffGB_Total_temp, KickoffGB_Total2020)","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:31:25.175712Z","iopub.execute_input":"2022-01-05T16:31:25.177205Z","iopub.status.idle":"2022-01-05T16:34:05.350520Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ggplot(KickoffGB_Total, aes(kickType))+\n geom_bar()+\n facet_wrap(~ goodorbad)","metadata":{"execution":{"iopub.status.busy":"2022-01-05T16:34:45.688970Z","iopub.execute_input":"2022-01-05T16:34:45.691136Z","iopub.status.idle":"2022-01-05T16:34:48.134631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Combining this plot with the previous conclude: All kicks result in negative result belong to Pooch kick - high for hangtime but not a lot of distance. The Muffed usually have a Deep Kick - your normal deep kick with decent hang time.\nThe teams  choosed and played more often Deepkick and avoided the  Pooch. And the good team actually did better than bad team.\n","metadata":{}},{"cell_type":"markdown","source":"It means in kickoff good teams play more deep ball","metadata":{}}]}