Welcome to the ballr [baw-ler], as in baller1. This is the R resource for your basketball-reference.com needs.
library(ballr)
library(magrittr)
library(ggplot2)
library(janitor)
library(scales)
Current standings
standings <- NBAStandingsByDate() # "YEAR-MO-DY"
standings
## $East
## eastern_conference w l w_lpercent gb pw pl ps_g pa_g
## 1 Toronto Raptors* 54 20 0.730 — 55 19 112.4 104.3
## 2 Boston Celtics* 50 23 0.685 3.5 46 27 104.3 100.3
## 3 Cleveland Cavaliers* 44 29 0.603 9.5 38 35 111.1 110.3
## 4 Indiana Pacers* 43 31 0.581 11 41 33 105.8 104.2
## 5 Philadelphia 76ers 42 30 0.583 11 43 29 108.5 105.5
## 6 Washington Wizards 40 33 0.548 13.5 39 34 107.0 106.0
## 7 Milwaukee Bucks 39 34 0.534 14.5 36 37 106.0 106.2
## 8 Miami Heat 39 35 0.527 15 38 36 103.3 103.1
## 9 Detroit Pistons 33 40 0.452 20.5 35 38 103.0 103.7
## 10 Charlotte Hornets 33 41 0.446 21 37 37 107.4 107.4
## 11 New York Knicks 27 47 0.365 27 29 45 104.2 107.5
## 12 Chicago Bulls 24 49 0.329 29.5 21 52 103.4 110.1
## 13 Brooklyn Nets 23 51 0.311 31 27 47 106.4 110.6
## 14 Orlando Magic 22 51 0.301 31.5 25 48 104.3 109.1
## 15 Atlanta Hawks 21 53 0.284 33 24 50 103.6 109.0
##
## $West
## western_conference w l w_lpercent gb pw pl ps_g pa_g
## 1 Houston Rockets* 60 14 0.811 — 56 18 113.5 104.4
## 2 Golden State Warriors* 54 19 0.740 5.5 52 21 114.4 107.2
## 3 Portland Trail Blazers 45 28 0.616 14.5 43 30 106.0 103.2
## 4 Oklahoma City Thunder 44 31 0.587 16.5 45 30 107.3 104.0
## 5 New Orleans Pelicans 43 31 0.581 17 38 36 111.4 111.0
## 6 San Antonio Spurs 43 31 0.581 17 45 29 102.4 99.2
## 7 Utah Jazz 42 32 0.568 18 45 29 103.5 100.2
## 8 Minnesota Timberwolves 42 32 0.568 18 42 32 110.0 107.7
## 9 Denver Nuggets 40 33 0.548 19.5 40 33 109.8 108.3
## 10 Los Angeles Clippers 39 34 0.534 20.5 39 34 109.6 108.7
## 11 Los Angeles Lakers 32 40 0.444 27 33 39 108.5 110.0
## 12 Sacramento Kings 24 50 0.324 36 20 54 99.4 106.8
## 13 Dallas Mavericks 22 51 0.301 37.5 30 43 102.7 105.3
## 14 Memphis Grizzlies 19 54 0.260 40.5 22 51 98.7 104.8
## 15 Phoenix Suns 19 55 0.257 41 16 58 104.0 113.9
Standings on an arbitrary date
standings <- NBAStandingsByDate("2015-12-31")
standings
## $East
## eastern_conference w l w_lpercent gb pw pl ps_g pa_g
## 1 Cleveland Cavaliers* 21 9 0.700 — 20 10 99.7 95.1
## 2 Atlanta Hawks* 21 13 0.618 2 19 15 102.0 100.1
## 3 Toronto Raptors* 20 13 0.606 2.5 20 13 99.8 96.4
## 4 Chicago Bulls 18 12 0.600 3 16 14 101.1 100.0
## 5 Orlando Magic 19 13 0.594 3 19 13 101.0 98.4
## 6 Miami Heat* 18 13 0.581 3.5 17 14 97.0 95.5
## 7 Indiana Pacers* 18 13 0.581 3.5 20 11 102.3 98.5
## 8 Boston Celtics* 18 14 0.563 4 20 12 103.1 99.1
## 9 Charlotte Hornets* 17 14 0.548 4.5 18 13 102.5 99.7
## 10 Detroit Pistons* 17 15 0.531 5 17 15 101.0 100.2
## 11 New York Knicks 15 18 0.455 7.5 15 18 98.0 99.5
## 12 Washington Wizards 14 16 0.467 7 12 18 101.5 104.4
## 13 Milwaukee Bucks 12 21 0.364 10.5 10 23 97.1 103.2
## 14 Brooklyn Nets 9 23 0.281 13 9 23 97.1 103.4
## 15 Philadelphia 76ers 3 31 0.088 20 5 29 92.5 104.4
##
## $West
## western_conference w l w_lpercent gb pw pl ps_g pa_g
## 1 Golden State Warriors* 29 2 0.935 — 26 5 114.1 101.8
## 2 San Antonio Spurs* 28 6 0.824 2.5 30 4 102.0 88.6
## 3 Oklahoma City Thunder* 22 10 0.688 7.5 24 8 108.6 100.4
## 4 Los Angeles Clippers* 20 13 0.606 10 19 14 103.1 100.9
## 5 Dallas Mavericks* 19 13 0.594 10.5 18 14 102.3 100.8
## 6 Memphis Grizzlies* 18 16 0.529 12.5 13 21 96.4 99.4
## 7 Houston Rockets* 16 17 0.485 14 15 18 104.1 105.5
## 8 Portland Trail Blazers* 14 20 0.412 16.5 16 18 101.3 102.0
## 9 Utah Jazz 13 17 0.433 15.5 14 16 96.6 97.3
## 10 Minnesota Timberwolves 12 20 0.375 17.5 14 18 100.4 102.6
## 11 Sacramento Kings 12 20 0.375 17.5 13 19 104.2 107.3
## 12 Denver Nuggets 12 21 0.364 18 11 22 98.9 103.8
## 13 Phoenix Suns 12 22 0.353 18.5 14 20 102.7 105.4
## 14 New Orleans Pelicans 10 21 0.323 19 11 20 102.1 107.0
## 15 Los Angeles Lakers 6 27 0.182 24 6 27 96.8 107.2
players <- NBAPerGameStatistics()
players
## # A tibble: 640 x 31
## rk player pos age tm g gs mp fg fga fgpercent
## <dbl> <chr> <chr> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1. Alex … SG 24. OKC 69. 8. 14.9 1.60 3.90 0.399
## 2 2. Quinc… PF 27. BRK 63. 8. 19.5 1.70 5.10 0.341
## 3 3. Steve… C 24. OKC 69. 69. 32.6 6.00 9.50 0.634
## 4 4. Bam A… C 20. MIA 64. 19. 20.2 2.60 5.00 0.514
## 5 5. Arron… SG 32. ORL 50. 3. 12.9 1.20 3.00 0.395
## 6 6. Cole … C 29. MIN 19. 0. 2.40 0.300 0.800 0.333
## 7 7. LaMar… C 32. SAS 67. 67. 33.5 9.20 18.0 0.508
## 8 8. Jarre… C 19. BRK 64. 23. 19.4 3.20 5.40 0.582
## 9 9. Kadee… PG 25. BOS 10. 0. 3.10 0.100 0.600 0.167
## 10 10. Tony … SF 36. NOP 22. 0. 12.4 2.00 4.10 0.484
## # ... with 630 more rows, and 20 more variables: x3p <dbl>, x3pa <dbl>,
## # x3ppercent <dbl>, x2p <dbl>, x2pa <dbl>, x2ppercent <dbl>,
## # efgpercent <dbl>, ft <dbl>, fta <dbl>, ftpercent <dbl>, orb <dbl>,
## # drb <dbl>, trb <dbl>, ast <dbl>, stl <dbl>, blk <dbl>, tov <dbl>,
## # pf <dbl>, ps_g <dbl>, link <chr>
players <- NBAPerGameStatistics(season = 2017)
players %>%
dplyr::filter(mp > 20, pos %in% c("SF")) %>%
dplyr::select(player, link) %>%
dplyr::distinct()
## # A tibble: 51 x 2
## player link
## <chr> <chr>
## 1 Justin Anderson /players/a/anderju01.html
## 2 Giannis Antetokounmpo /players/a/antetgi01.html
## 3 Carmelo Anthony /players/a/anthoca01.html
## 4 Trevor Ariza /players/a/arizatr01.html
## 5 Matt Barnes /players/b/barnema02.html
## 6 Kent Bazemore /players/b/bazemke01.html
## 7 Bojan Bogdanovic /players/b/bogdabo02.html
## 8 Jimmy Butler /players/b/butleji01.html
## 9 DeMarre Carroll /players/c/carrode01.html
## 10 Vince Carter /players/c/cartevi01.html
## # ... with 41 more rows
players <- NBAPerGameStatisticsPer36Min(season = 2017)
players
## # A tibble: 595 x 30
## rk player pos age tm g gs mp fg fga fgpercent
## <dbl> <chr> <chr> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1. Alex A… SG 23. OKC 68. 6. 1055. 4.60 11.6 0.393
## 2 2. Quincy… PF 26. TOT 38. 1. 558. 4.50 11.0 0.412
## 3 2. Quincy… PF 26. DAL 6. 0. 48. 3.70 12.7 0.294
## 4 2. Quincy… PF 26. BRK 32. 1. 510. 4.60 10.8 0.425
## 5 3. Steven… C 23. OKC 80. 80. 2389. 5.60 9.90 0.571
## 6 4. Arron … SG 31. SAC 61. 45. 1580. 4.20 9.60 0.440
## 7 5. Alexis… C 28. NOP 39. 15. 584. 5.50 11.0 0.500
## 8 6. Cole A… C 28. MIN 62. 0. 531. 3.10 5.80 0.523
## 9 7. LaMarc… PF 31. SAS 72. 72. 2335. 7.70 16.2 0.477
## 10 8. Lavoy … PF 27. IND 61. 5. 871. 3.20 6.90 0.458
## # ... with 585 more rows, and 19 more variables: x3p <dbl>, x3pa <dbl>,
## # x3ppercent <dbl>, x2p <dbl>, x2pa <dbl>, x2ppercent <dbl>, ft <dbl>,
## # fta <dbl>, ftpercent <dbl>, orb <dbl>, drb <dbl>, trb <dbl>,
## # ast <dbl>, stl <dbl>, blk <dbl>, tov <dbl>, pf <dbl>, pts <dbl>,
## # link <chr>
players <- NBAPerGameStatisticsPer36Min(season = 2017) %>%
dplyr::filter(pos %in% c("C", "PF")) %>%
dplyr::top_n(n = 10, pts) %>%
dplyr::select(player, link) %>%
dplyr::distinct()
players
## # A tibble: 8 x 2
## player link
## <chr> <chr>
## 1 DeMarcus Cousins /players/c/couside01.html
## 2 Anthony Davis /players/d/davisan02.html
## 3 Kevin Durant /players/d/duranke01.html
## 4 Joel Embiid /players/e/embiijo01.html
## 5 Enes Kanter /players/k/kanteen01.html
## 6 Brook Lopez /players/l/lopezbr01.html
## 7 Boban Marjanovic /players/m/marjabo01.html
## 8 Karl-Anthony Towns /players/t/townska01.html
Query each player in the list
player_stats <- NBAPlayerPerGameStats(players[1, 2]) %>%
dplyr::filter(!is.na(age)) %>%
dplyr::mutate(player = as.character(players[1, 1]))
Append the stats from each player into a df
for(i in 2:dim(players)[1]){
tmp <- NBAPlayerPerGameStats(players[i, 2]) %>%
dplyr::filter(!is.na(age)) %>%
dplyr::mutate(player = as.character(players[i, 1]))
player_stats <- dplyr::bind_rows(player_stats, tmp)
}
Plot everything
p <- ggplot2::ggplot(data = player_stats,
aes(x = age, y = efgpercent, group = player))
p + ggplot2::geom_line(alpha = .25) +
ggplot2::geom_point(alpha = .25) +
ggplot2::scale_y_continuous("effective field goal %age", limit = c(0, 1),
labels = percent) +
ggplot2::geom_line(data = dplyr::filter(player_stats, player == "Anthony Davis"),
aes(x = age, y = efgpercent), size = 1, col = "#1f78b4") +
ggplot2::geom_point(data = dplyr::filter(player_stats, player == "Anthony Davis"),
aes(x = age, y = efgpercent), size = 1, col = "#1f78b4") +
ggplot2::geom_line(data = dplyr::filter(player_stats, player == "DeMarcus Cousins"),
aes(x = age, y = efgpercent), size = 1, col = "#33a02c") +
ggplot2::geom_point(data = dplyr::filter(player_stats, player == "DeMarcus Cousins"),
aes(x = age, y = efgpercent), size = 1, col = "#33a02c") +
ggplot2::theme_bw()
per_100 <- NBAPerGameStatisticsPer100Poss(season = 2018)
utils::head(per_100)
## rk player pos age tm g gs mp fg fga fgpercent x3p x3pa
## 1 1 Alex Abrines SG 24 OKC 69 8 1029 5.2 13.0 0.399 3.8 9.7
## 2 2 Quincy Acy PF 27 BRK 63 8 1229 4.4 12.8 0.341 3.4 10.2
## 3 3 Steven Adams C 24 OKC 69 69 2249 9.2 14.4 0.634 0.0 0.0
## 4 4 Bam Adebayo C 20 MIA 64 19 1293 6.4 12.5 0.514 0.0 0.3
## 5 5 Arron Afflalo SG 32 ORL 50 3 647 4.5 11.5 0.395 1.9 4.8
## 6 6 Cole Aldrich C 29 MIN 19 0 46 5.4 16.3 0.333 0.0 0.0
## x3ppercent x2p x2pa x2ppercent ft fta ftpercent orb drb trb ast stl
## 1 0.390 1.4 3.3 0.426 1.6 1.9 0.872 1.2 4.0 5.1 1.3 1.7
## 2 0.335 0.9 2.6 0.364 1.8 2.2 0.821 1.5 7.9 9.4 2.1 1.1
## 3 0.000 9.2 14.4 0.636 3.3 5.7 0.572 7.8 5.9 13.7 1.7 1.9
## 4 0.000 6.4 12.2 0.525 4.7 6.6 0.710 4.4 9.6 14.0 3.8 1.1
## 5 0.391 2.6 6.6 0.398 1.7 2.0 0.846 0.3 4.7 5.0 2.2 0.3
## 6 NA 5.4 16.3 0.333 2.2 6.5 0.333 3.3 10.9 14.1 2.2 2.2
## blk tov pf pts x ortg drtg link
## 1 0.4 1.2 5.5 15.8 NA 116 110 /players/a/abrinal01.html
## 2 1.0 2.3 5.3 13.9 NA 96 111 /players/a/acyqu01.html
## 3 1.7 2.5 4.4 21.6 NA 127 107 /players/a/adamsst01.html
## 4 1.5 2.4 5.2 17.5 NA 117 106 /players/a/adebaba01.html
## 5 0.6 1.6 4.1 12.6 NA 98 115 /players/a/afflaar01.html
## 6 1.1 1.1 12.0 13.0 NA 83 108 /players/a/aldrico01.html
adv_stats <- NBAPerGameAdvStatistics(season = 2018)
utils::head(adv_stats)
## rk player pos age tm g mp per tspercent x3par ftr
## 1 1 Alex Abrines SG 24 OKC 69 1029 9.3 0.572 0.746 0.146
## 2 2 Quincy Acy PF 27 BRK 63 1229 7.4 0.506 0.796 0.173
## 3 3 Steven Adams C 24 OKC 69 2249 21.3 0.636 0.003 0.394
## 4 4 Bam Adebayo C 20 MIA 64 1293 15.7 0.569 0.022 0.526
## 5 5 Arron Afflalo SG 32 ORL 50 647 5.6 0.511 0.421 0.171
## 6 6 Cole Aldrich C 29 MIN 19 46 5.2 0.340 0.000 0.400
## orbpercent drbpercent trbpercent astpercent stlpercent blkpercent
## 1 2.5 9.2 5.7 3.6 1.7 0.7
## 2 3.2 17.4 10.2 6.1 1.1 1.5
## 3 17.0 13.7 15.4 5.2 1.9 3.1
## 4 9.8 21.7 15.7 11.3 1.1 2.6
## 5 0.7 10.7 5.7 6.2 0.3 1.0
## 6 7.5 25.3 16.3 5.8 2.2 1.9
## tovpercent usgpercent x ows dws ws ws_48 x_2 obpm dbpm bpm vorp
## 1 8.1 13.0 NA 1.2 0.9 2.1 0.097 NA -0.5 -1.7 -2.2 -0.1
## 2 14.3 14.3 NA -0.4 1.0 0.6 0.023 NA -2.5 -0.2 -2.8 -0.2
## 3 12.7 16.8 NA 6.4 2.8 9.3 0.198 NA 2.5 1.2 3.7 3.2
## 4 13.4 15.9 NA 2.2 1.8 4.0 0.147 NA -1.5 1.8 0.2 0.7
## 5 11.4 12.5 NA -0.1 0.2 0.0 0.004 NA -4.2 -1.8 -6.0 -0.6
## 6 5.4 17.9 NA -0.1 0.1 0.0 -0.031 NA -7.4 -0.6 -8.0 -0.1
## link
## 1 /players/a/abrinal01.html
## 2 /players/a/acyqu01.html
## 3 /players/a/adamsst01.html
## 4 /players/a/adebaba01.html
## 5 /players/a/afflaar01.html
## 6 /players/a/aldrico01.html
Look at selector gadget for a team’s website, e.g. Denver Nuggets. Suppose you want to find everybody who played for the Nuggets last year, and then their stats. Remember to use Chrome (ugh).
library(rvest)
## Loading required package: xml2
url <- "http://www.basketball-reference.com/teams/DEN/2017.html"
links <- xml2::read_html(url) %>%
rvest::html_nodes(".center+ .left a") %>%
rvest::html_attr('href')
links
## [1] "/players/a/arthuda01.html" "/players/b/bartowi01.html"
## [3] "/players/b/beaslma01.html" "/players/c/chandwi01.html"
## [5] "/players/f/farieke01.html" "/players/g/gallida01.html"
## [7] "/players/g/geeal01.html" "/players/h/harriga01.html"
## [9] "/players/h/hernaju01.html" "/players/h/hibbero01.html"
## [11] "/players/j/jokicni01.html" "/players/m/millemi01.html"
## [13] "/players/m/mudiaem01.html" "/players/m/murraja01.html"
## [15] "/players/n/nelsoja01.html" "/players/n/nurkiju01.html"
## [17] "/players/o/obryajo01.html" "/players/p/plumlma01.html"
## [19] "/players/s/stokeja01.html"