// two "supported" packages, we can skip the full dependency & import boilerplate
%use lets-plot, krangl
// csv is courtesy of pro-football-reference: https://www.pro-football-reference.com/years/NFL/passing.htm
val dfPassing = DataFrame.readCSV("nfl_passing.csv")
dfPassing
Rk | Year | Tms | Cmp | Att | Cmp% | Yds | TD | TD% | Int | Int% | Y/A | AY/A | Y/C | Y/G | Rate | Sk | SkYds | NY/A | ANY/A | Sk% |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 2020 | 32 | 2884 | 4329 | 66.6 | 30510 | 218 | 5.0 | 94 | 2.2 | 7.5 | 7.5 | 11.2 | 250.1 | 96.5 | 278 | 1839 | 6.62 | 6.7 | 6.0 |
2 | 2019 | 32 | 11331 | 17853 | 63.5 | 120301 | 797 | 4.5 | 410 | 2.3 | 7.2 | 7.1 | 11.4 | 235.0 | 90.4 | 1276 | 8610 | 6.29 | 6.2 | 6.7 |
3 | 2018 | 32 | 11462 | 17671 | 64.9 | 121737 | 847 | 4.8 | 419 | 2.4 | 7.4 | 7.3 | 11.4 | 237.8 | 92.9 | 1281 | 8530 | 6.42 | 6.3 | 6.8 |
4 | 2017 | 32 | 10856 | 17488 | 62.1 | 114870 | 741 | 4.2 | 430 | 2.5 | 7.0 | 6.8 | 11.3 | 224.4 | 86.9 | 1195 | 7810 | 6.15 | 5.9 | 6.4 |
5 | 2016 | 32 | 11526 | 18295 | 63.0 | 123639 | 786 | 4.3 | 415 | 2.3 | 7.2 | 7.0 | 11.4 | 241.5 | 89.3 | 1118 | 7225 | 6.37 | 6.2 | 5.8 |
6 | 2015 | 32 | 11527 | 18298 | 63.0 | 124843 | 842 | 4.6 | 436 | 2.4 | 7.3 | 7.1 | 11.5 | 243.8 | 90.2 | 1187 | 7850 | 6.41 | 6.3 | 6.1 |
7 | 2014 | 32 | 11200 | 17879 | 62.6 | 121247 | 807 | 4.5 | 450 | 2.5 | 7.2 | 7.0 | 11.5 | 236.8 | 88.9 | 1212 | 7651 | 6.35 | 6.1 | 6.3 |
8 | 2013 | 32 | 11102 | 18136 | 61.2 | 120626 | 804 | 4.4 | 502 | 2.8 | 7.1 | 6.8 | 11.6 | 235.6 | 86.0 | 1295 | 8551 | 6.21 | 5.9 | 6.7 |
9 | 2012 | 32 | 10833 | 17788 | 60.9 | 118418 | 757 | 4.3 | 468 | 2.6 | 7.1 | 6.7 | 11.6 | 231.3 | 85.6 | 1169 | 7533 | 6.25 | 5.9 | 6.2 |
10 | 2011 | 32 | 10464 | 17410 | 60.1 | 117601 | 745 | 4.3 | 506 | 2.9 | 7.2 | 6.7 | 12.0 | 229.7 | 84.3 | 1188 | 7729 | 6.32 | 5.9 | 6.4 |
11 | 2010 | 32 | 10491 | 17269 | 60.8 | 113450 | 751 | 4.3 | 511 | 3.0 | 7.0 | 6.5 | 11.5 | 221.6 | 84.1 | 1130 | 7514 | 6.17 | 5.7 | 6.1 |
12 | 2009 | 32 | 10372 | 17033 | 60.9 | 111851 | 710 | 4.2 | 525 | 3.1 | 7.0 | 6.4 | 11.5 | 218.5 | 83.0 | 1101 | 7066 | 6.17 | 5.6 | 6.1 |
13 | 2008 | 32 | 10081 | 16526 | 61.0 | 108177 | 646 | 3.9 | 465 | 2.8 | 6.9 | 6.5 | 11.4 | 211.3 | 83.2 | 1036 | 6589 | 6.16 | 5.7 | 5.9 |
14 | 2007 | 32 | 10425 | 17045 | 61.2 | 109722 | 720 | 4.2 | 534 | 3.1 | 6.9 | 6.3 | 11.2 | 214.3 | 82.6 | 1102 | 7152 | 6.05 | 5.5 | 6.1 |
15 | 2006 | 32 | 9796 | 16389 | 59.8 | 104861 | 648 | 4.0 | 520 | 3.2 | 6.9 | 6.2 | 11.5 | 204.8 | 80.4 | 1164 | 7416 | 5.97 | 5.4 | 6.6 |
16 | 2005 | 32 | 9790 | 16464 | 59.5 | 104168 | 644 | 3.9 | 506 | 3.1 | 6.8 | 6.2 | 11.4 | 203.5 | 80.1 | 1182 | 7553 | 5.90 | 5.3 | 6.7 |
17 | 2004 | 32 | 9772 | 16354 | 59.8 | 107797 | 732 | 4.5 | 524 | 3.2 | 7.1 | 6.5 | 11.8 | 210.5 | 82.8 | 1196 | 7541 | 6.14 | 5.6 | 6.8 |
18 | 2003 | 32 | 9695 | 16493 | 58.8 | 102628 | 654 | 4.0 | 538 | 3.3 | 6.6 | 6.0 | 11.3 | 200.4 | 78.3 | 1092 | 6839 | 5.84 | 5.2 | 6.2 |
19 | 2002 | 32 | 10314 | 17292 | 59.6 | 108661 | 694 | 4.0 | 528 | 3.1 | 6.7 | 6.1 | 11.3 | 212.2 | 80.4 | 1175 | 7540 | 5.88 | 5.3 | 6.4 |
20 | 2001 | 31 | 9542 | 16181 | 59.0 | 102080 | 635 | 3.9 | 545 | 3.4 | 6.8 | 6.0 | 11.5 | 205.8 | 78.5 | 1196 | 7559 | 5.87 | 5.2 | 6.9 |
... only showing top 20 rows
val mapPassing = dfPassing.filter { (it["Year"] lt 2020) AND (it["Year"] gt 1989) }.toMap()
mapPassing
{Rk=[Ljava.lang.Integer;@ffbdb79, Year=[Ljava.lang.Integer;@67ea360f, Tms=[Ljava.lang.Integer;@3c9a8c66, Cmp=[Ljava.lang.Integer;@16abeca6, Att=[Ljava.lang.Integer;@475add19, Cmp%=[Ljava.lang.Double;@7136d1b3, Yds=[Ljava.lang.Integer;@19a78a4f, TD=[Ljava.lang.Integer;@50208b01, TD%=[Ljava.lang.Double;@41833609, Int=[Ljava.lang.Integer;@67fdcc3, Int%=[Ljava.lang.Double;@232fcbb1, Y/A=[Ljava.lang.Double;@77833456, AY/A=[Ljava.lang.Double;@2f6867d1, Y/C=[Ljava.lang.Double;@57893f3b, Y/G=[Ljava.lang.Double;@aa60438, Rate=[Ljava.lang.Double;@6469a0be, Sk=[Ljava.lang.String;@853050d, SkYds=[Ljava.lang.String;@163d83db, NY/A=[Ljava.lang.String;@2c80d2e0, ANY/A=[Ljava.lang.String;@545fb9e, Sk%=[Ljava.lang.String;@152eed56}
val p = lets_plot(mapPassing) { x = "Year"; y = "AY/A" } + ggsize(640, 240)
p + geom_bar(stat=Stat.identity) +
ggtitle("Avg Adjusted Yds/Attempt per NFL regular season")
val p = lets_plot(mapPassing) { x = "Year"; y = "Rate" } + ggsize(640, 240)
p + geom_bar(stat=Stat.identity) +
ggtitle("Total Combined Passer Rating per NFL regular season")
val dfPassingRanges = dfPassing
.filter { (it["Year"] lt 2020) AND (it["Year"] gt 1989) }
.addColumn("YearRange") { it["Year"].map<Double>{ floor(it.div(5.0)).times(5).toInt() }}
.addColumn("Years") { it["YearRange"].map<Int>{ "$it - ${it + 4}" }}
val mapPassingRanges = dfPassingRanges
.select({ listOf("Year", "AY/A", "Rate", "YearRange", "Years") })
.groupBy("YearRange", "Years")
.summarize(
"mean_AY/A" to { it["AY/A"].mean(removeNA = true) },
"mean_Rate" to { it["Rate"].mean(removeNA = true) }
).toMap()
val xlimits = listOf("1990 - 1994", "1995 - 1999", "2000 - 2004", "2005 - 2009", "2010 - 2014", "2015 - 2019")
val p = lets_plot(mapPassingRanges) { x = "Years"; y = "mean_AY/A" } + ggsize(720, 240)
p + geom_bar(stat=Stat.identity) + scale_x_discrete(limits = xlimits) +
scale_y_continuous(limits = Pair(4.0, 8.0)) +
ggtitle("Average Adjusted Yards/Attempt per NFL regular season")
val p = lets_plot(mapPassingRanges) { x = "Years"; y = "mean_Rate" } + ggsize(720, 240)
p + geom_bar(stat=Stat.identity) + scale_x_discrete(limits = xlimits) +
ggtitle("Total Combined Passer Rating per NFL regular season")