If you are like me and love sports, data, and visualization [which will come in the form of GIF's and JPG's today] this post is for you. In this tutorial we will learn how to harness power of R to build a function that gives us access to data from Basketball Reference.
In order to partake in this adventure we will need these powerful weapons in your arsenal. First make sure you have R and RStudio installed. Then if you don’t already use Firefox or Chrome pick a browser horse and install it. Finally, launch your chosen browse and install the fantastic SelectorGadget widget. Fire up , crack your knuckles and finish any other pre-game routines, it’s game time.
Now that we are ready, we must decide what exactly to explore. Being a huge fan of THE and still being on cloud 9 from our recent beatdown of the despised New York Knickerbockers I’ve decided to explore NBA team data from my favorite NBA data site Basketball Reference.
After some navigation through the links on the home page we find what we want, the Seasons Index page. Let’s look at the 2013-2014 season. Looks like the page is essentially a bunch of tables, fantastic news for data scraping. Let’s try to pull in the Team Stats table. Use the Selector widget and navigate to the bottom of the Team Stats and click such that an orange box surrounds the table. A pop up with the text #team should appear.
Booya, that’s the CSS Selector for the table. With this information we know what is needed to bring this data into R. Navigate back into RStudio, fire up a new R Script file because its data scraping time.
Once in the script we need to load the packages needed to bring us to victory. I am about to start embedding code but before I do here a few quick notes. As a self taught coder I like to code left to right and assign using ->, something for some strange reason, is frowned upon by the authority. Most people code right to left and assign using <- but it’s a free country, and I like to code how I read but you can do it however you like, there is no wrong answer just being able to do things or not.
Next point, there is a new craze hitting R that all the cool kids are using, it’s called piping and it is used with the symbols %>% or %>>%, think of it like the word THEN, I prefer the %>>% syntax from the fantastic pipeR package. Finally anytime you see # it is a comment that the code will skip, please pardon my jibberish but I hope you can understand most of my comments.
c('rvest','dplyr','pipeR', 'knitr') -> packages # you don't need knitr but I do to make this post
#dplyr or pipeR use the install.packages function to install them, install.packages('dplyr') and install.packages('pipeR')
#If you don't have rvest do the following - install devtools, install.packages('devtools')
#Load devtools using library(devtools) and then install rvest by using install_github('hadley/rvest')
lapply(packages, library, character.only = T) #loops through the packages and loads them
##
## Attaching package: 'rvest'
##
## The following object is masked from 'package:utils':
##
## history
##
##
## Attaching package: 'dplyr'
##
## The following object is masked from 'package:stats':
##
## filter
##
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
## [[1]]
## [1] "rvest" "stats" "graphics" "grDevices" "utils" "datasets"
## [7] "methods" "base"
##
## [[2]]
## [1] "dplyr" "rvest" "stats" "graphics" "grDevices" "utils"
## [7] "datasets" "methods" "base"
##
## [[3]]
## [1] "pipeR" "dplyr" "rvest" "stats" "graphics"
## [6] "grDevices" "utils" "datasets" "methods" "base"
##
## [[4]]
## [1] "knitr" "pipeR" "dplyr" "rvest" "stats"
## [6] "graphics" "grDevices" "utils" "datasets" "methods"
## [11] "base"
Step 1 lets get the table into R. Since we want scale this to other tables we are going to turn off the headers and see if we can find the row with the column names. In Basketball-References all the stats tables usually start with a column called Rk or rank.
It looks like the headers are in the first row [but in some cases its the second]. Let’s extract out that row and place it into a character vector. Next we use that vector to name our Data Frame [what r calls the table with all the data in it]. Since R is a case sensitive language it’s good practice to use lower case headers and we will do that here. Also R hates things likes spaces or characters like % or / in headers so let’s replace any of those with a period. Finally we want to skip the row with the headers and in order to prepare ourselves for the function we will soon write, we want to find the row the headers are in and then take the data from the row after that until the end.
'http://www.basketball-reference.com/leagues/NBA_2014.html' -> url
'#team' -> css_page
url %>>%
html %>>%
html_nodes(css_page) %>>%
html_table(header = F) %>>%
data.frame() %>>%
tbl_df() -> total_table
total_table %>>%
filter(X.1 == 'Rk') %>>% as.character -> names
'Rk' %>>% grep(x = total_table$X.1) -> row_of_header #find where rank is
names %>>% tolower -> names(total_table)
names(total_table) %>>% (gsub('\\%|/','\\.',.)) -> names(total_table)
(row_of_header + 1) %>>% (total_table[.:nrow(total_table),]) -> total_table #skip that row and go to the end row and go to the end
total_table %>>% head
## Source: local data frame [6 x 26]
##
## rk team g mp fg fga fg. 3p 3pa 3p. 2p
## 1 1 Los Angeles Clippers* 82 19755 3208 6761 .474 693 1966 .352 2515
## 2 2 Houston Rockets* 82 19830 3118 6603 .472 779 2179 .358 2339
## 3 3 Minnesota Timberwolves 82 19855 3189 7175 .444 600 1757 .341 2589
## 4 4 Portland Trail Blazers* 82 19855 3207 7134 .450 770 2071 .372 2437
## 5 5 Oklahoma City Thunder* 82 19805 3194 6782 .471 664 1839 .361 2530
## 6 6 San Antonio Spurs* 82 19755 3326 6844 .486 698 1757 .397 2628
## Variables not shown: 2pa (chr), 2p. (chr), ft (chr), fta (chr), ft. (chr),
## orb (chr), drb (chr), trb (chr), ast (chr), stl (chr), blk (chr), tov
## (chr), pf (chr), pts (chr), pts.g (chr)
Now you will see a Data Frame in your workspace called total_table, we already found and replaced the headers but there are still a few more quick data cleaning chores remaining before you have a clean dataset. It looks like there are asterisks at the end of some of the team’s that indicate whether the team made the playoffs, sorry Knicks fans. Let’s add a logical column for teams that made the playoffs and then remove the astericks. Next let’s remove the rank column and get rid of the row with the league averages since that is not an actual team and we can easily recalculate summary statistics when we need them.
team | g | mp | fg | fga | fg. | 3p | 3pa | 3p. | 2p | 2pa | 2p. | ft | fta | ft. | orb | drb | trb | ast | stl | blk | tov | pf | pts | pts.g | playoff_team |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Los Angeles Clippers | 82 | 19755 | 3208 | 6761 | .474 | 693 | 1966 | .352 | 2515 | 4795 | .525 | 1741 | 2384 | .730 | 858 | 2668 | 3526 | 2016 | 703 | 397 | 1136 | 1767 | 8850 | 107.9 | TRUE |
Houston Rockets | 82 | 19830 | 3118 | 6603 | .472 | 779 | 2179 | .358 | 2339 | 4424 | .529 | 1814 | 2549 | .712 | 920 | 2797 | 3717 | 1755 | 621 | 461 | 1323 | 1676 | 8829 | 107.7 | TRUE |
Minnesota Timberwolves | 82 | 19855 | 3189 | 7175 | .444 | 600 | 1757 | .341 | 2589 | 5418 | .478 | 1790 | 2301 | .778 | 1024 | 2644 | 3668 | 1963 | 718 | 297 | 1142 | 1504 | 8768 | 106.9 | FALSE |
Portland Trail Blazers | 82 | 19855 | 3207 | 7134 | .450 | 770 | 2071 | .372 | 2437 | 5063 | .481 | 1569 | 1926 | .815 | 1022 | 2786 | 3808 | 1904 | 454 | 387 | 1125 | 1576 | 8753 | 106.7 | TRUE |
Oklahoma City Thunder | 82 | 19805 | 3194 | 6782 | .471 | 664 | 1839 | .361 | 2530 | 4943 | .512 | 1653 | 2052 | .806 | 887 | 2781 | 3668 | 1794 | 678 | 501 | 1256 | 1858 | 8705 | 106.2 | TRUE |
San Antonio Spurs | 82 | 19755 | 3326 | 6844 | .486 | 698 | 1757 | .397 | 2628 | 5087 | .517 | 1289 | 1642 | .785 | 762 | 2786 | 3548 | 2064 | 604 | 420 | 1180 | 1495 | 8639 | 105.4 | TRUE |
Phoenix Suns | 82 | 19755 | 3172 | 6845 | .463 | 765 | 2055 | .372 | 2407 | 4790 | .503 | 1520 | 2004 | .758 | 928 | 2601 | 3529 | 1563 | 688 | 374 | 1258 | 1798 | 8629 | 105.2 | FALSE |
Dallas Mavericks | 82 | 19830 | 3249 | 6858 | .474 | 721 | 1877 | .384 | 2528 | 4981 | .508 | 1378 | 1733 | .795 | 840 | 2514 | 3354 | 1935 | 704 | 356 | 1110 | 1636 | 8597 | 104.8 | TRUE |
Denver Nuggets | 82 | 19755 | 3147 | 7042 | .447 | 702 | 1959 | .358 | 2445 | 5083 | .481 | 1563 | 2154 | .726 | 1009 | 2717 | 3726 | 1838 | 615 | 459 | 1305 | 1890 | 8559 | 104.4 | FALSE |
Golden State Warriors | 82 | 19830 | 3236 | 7005 | .462 | 774 | 2037 | .380 | 2462 | 4968 | .496 | 1303 | 1731 | .753 | 896 | 2819 | 3715 | 1912 | 642 | 407 | 1247 | 1784 | 8549 | 104.3 | TRUE |
Los Angeles Lakers | 82 | 19705 | 3139 | 6980 | .450 | 774 | 2032 | .381 | 2365 | 4948 | .478 | 1390 | 1835 | .757 | 745 | 2620 | 3365 | 2006 | 611 | 446 | 1239 | 1627 | 8442 | 103.0 | FALSE |
Miami Heat | 82 | 19880 | 3142 | 6272 | .501 | 665 | 1829 | .364 | 2477 | 4443 | .558 | 1431 | 1884 | .760 | 627 | 2397 | 3024 | 1847 | 732 | 367 | 1212 | 1596 | 8380 | 102.2 | TRUE |
Toronto Raptors | 82 | 19955 | 2992 | 6718 | .445 | 713 | 1917 | .372 | 2279 | 4801 | .475 | 1608 | 2055 | .782 | 935 | 2552 | 3487 | 1737 | 577 | 343 | 1159 | 1882 | 8305 | 101.3 | TRUE |
Atlanta Hawks | 82 | 19830 | 3061 | 6688 | .458 | 768 | 2116 | .363 | 2293 | 4572 | .502 | 1392 | 1782 | .781 | 713 | 2565 | 3278 | 2041 | 680 | 326 | 1251 | 1577 | 8282 | 101.0 | TRUE |
Detroit Pistons | 82 | 19780 | 3182 | 7124 | .447 | 507 | 1580 | .321 | 2675 | 5544 | .483 | 1415 | 2111 | .670 | 1196 | 2525 | 3721 | 1714 | 687 | 395 | 1193 | 1666 | 8286 | 101.0 | FALSE |
Washington Wizards | 82 | 20055 | 3177 | 6920 | .459 | 647 | 1704 | .380 | 2530 | 5216 | .485 | 1253 | 1715 | .731 | 886 | 2573 | 3459 | 1909 | 668 | 377 | 1204 | 1675 | 8254 | 100.7 | TRUE |
Sacramento Kings | 82 | 19830 | 3026 | 6766 | .447 | 491 | 1475 | .333 | 2535 | 5291 | .479 | 1698 | 2237 | .759 | 990 | 2656 | 3646 | 1547 | 587 | 318 | 1249 | 1849 | 8241 | 100.5 | FALSE |
New Orleans Pelicans | 82 | 19855 | 3101 | 6761 | .459 | 486 | 1303 | .373 | 2615 | 5458 | .479 | 1489 | 1936 | .769 | 933 | 2486 | 3419 | 1745 | 647 | 523 | 1129 | 1857 | 8177 | 99.7 | FALSE |
Philadelphia 76ers | 82 | 19855 | 3108 | 7150 | .435 | 577 | 1847 | .312 | 2531 | 5303 | .477 | 1362 | 1918 | .710 | 949 | 2556 | 3505 | 1791 | 765 | 330 | 1384 | 1844 | 8155 | 99.5 | FALSE |
New York Knicks | 82 | 19855 | 3027 | 6739 | .449 | 759 | 2038 | .372 | 2268 | 4701 | .482 | 1271 | 1670 | .761 | 870 | 2437 | 3307 | 1641 | 631 | 367 | 1063 | 1815 | 8084 | 98.6 | FALSE |
Brooklyn Nets | 82 | 19880 | 2931 | 6391 | .459 | 709 | 1922 | .369 | 2222 | 4469 | .497 | 1508 | 2002 | .753 | 721 | 2407 | 3128 | 1714 | 705 | 311 | 1191 | 1777 | 8079 | 98.5 | TRUE |
Cleveland Cavaliers | 82 | 19930 | 3036 | 6955 | .437 | 584 | 1640 | .356 | 2452 | 5315 | .461 | 1398 | 1861 | .751 | 989 | 2629 | 3618 | 1738 | 579 | 304 | 1163 | 1640 | 8054 | 98.2 | FALSE |
Charlotte Bobcats | 82 | 19905 | 2976 | 6730 | .442 | 516 | 1471 | .351 | 2460 | 5259 | .468 | 1474 | 2000 | .737 | 776 | 2724 | 3500 | 1778 | 499 | 421 | 1010 | 1493 | 7942 | 96.9 | TRUE |
Indiana Pacers | 82 | 19780 | 2949 | 6573 | .449 | 550 | 1542 | .357 | 2399 | 5031 | .477 | 1485 | 1907 | .779 | 834 | 2831 | 3665 | 1651 | 550 | 446 | 1237 | 1675 | 7933 | 96.7 | TRUE |
Orlando Magic | 82 | 19955 | 3022 | 6784 | .445 | 563 | 1596 | .353 | 2459 | 5188 | .474 | 1307 | 1714 | .763 | 794 | 2654 | 3448 | 1726 | 630 | 350 | 1222 | 1678 | 7914 | 96.5 | FALSE |
Boston Celtics | 82 | 19730 | 2996 | 6883 | .435 | 575 | 1729 | .333 | 2421 | 5154 | .470 | 1325 | 1706 | .777 | 980 | 2505 | 3485 | 1726 | 584 | 343 | 1261 | 1743 | 7892 | 96.2 | FALSE |
Memphis Grizzlies | 82 | 19805 | 3122 | 6723 | .464 | 405 | 1147 | .353 | 2717 | 5576 | .487 | 1235 | 1666 | .741 | 950 | 2526 | 3476 | 1792 | 631 | 375 | 1124 | 1568 | 7884 | 96.1 | TRUE |
Milwaukee Bucks | 82 | 19880 | 2952 | 6737 | .438 | 548 | 1553 | .353 | 2404 | 5184 | .464 | 1377 | 1843 | .747 | 971 | 2399 | 3370 | 1760 | 541 | 403 | 1238 | 1713 | 7829 | 95.5 | FALSE |
Utah Jazz | 82 | 19780 | 2951 | 6652 | .444 | 543 | 1577 | .344 | 2408 | 5075 | .474 | 1346 | 1803 | .747 | 904 | 2477 | 3381 | 1664 | 570 | 366 | 1200 | 1699 | 7791 | 95.0 | FALSE |
Chicago Bulls | 82 | 19930 | 2843 | 6577 | .432 | 508 | 1459 | .348 | 2335 | 5118 | .456 | 1486 | 1908 | .779 | 937 | 2683 | 3620 | 1860 | 594 | 424 | 1223 | 1565 | 7680 | 93.7 | TRUE |
total_table %>>% write.csv('Desktop/2014_team_data.csv', row.names = F)
Now that we know how to pull the table from page let’s teach R how to do this as a function with inputs. If we accomplish this we can do cool things like loop through all the seasons since 1951 or pull in different tables from the page. We will become masters of all NBA team data with just a few inputs, an internet connection and R.
The key to making this work is understanding the structure of the URL. Thankfully our friends at Sports Reference make it easy for us. The URL structure consist of 3 things, the base, the league and the year end of the season. We can easily teach our function to create this by pasting the 3 inputs together to form a URL.
We know how to scrape the table once we have a URL from earlier. We also want to extract out the team ID’s which we can get from the URL’s on the page mirroring how we scrape a table except looking for XML tags with //a and a hyperlink. This process requires some data cleaning as well to extract out just the team id.
Since we can scale this function we want add to the Data Frame the season and table name from the page [team, opponent, and misc are in every season but there are more you can use if you look through various years] as this function will find whichever table you ask it to. Finally we want to give ourself the ability to timestamp if we want to keep track of changes in the data for the current season or run a Sports Reference to automatically scrape the data each day of the season.
So here’s our beloved getBREFTeamStatTable function.
getBREFTeamStatTable <- function(season_end = 2015, table_name = 'team', date = T){
c('rvest','dplyr','pipeR') -> packages
lapply(packages, library, character.only = T)
'http://www.basketball-reference.com/leagues/' -> base
'NBA' -> league
'#' %>>% paste0(table_name) -> css_page
css_page %>>% paste0(" , ", css_page,' a') -> css_id
table_name %>>% tolower -> table_name
table_name %>>% paste('stats', sep = "_") -> table
base %>>% paste0(league,'_',season_end,".html") -> url
url %>>% ## get table
html %>>%
html_nodes(css_page) %>>%
html_table(header = F) %>>% data.frame() %>>% tbl_df() -> df
if(df$X.1[1] == 'Rk'){
df %>>%
filter(X.1 == "Rk") %>>% as.character -> names
'Rk' %>>% grep(x = df$X.1) -> row_of_header #find where rank is
(row_of_header + 1) %>>% (df[.:nrow(df),]) -> df #skip that row and go to the end
names %>>% tolower-> names(df)} else{
df %>>%
filter(X.1 == "Rk") %>>% as.character -> names
'Rk' %>>% grep(x = df$X.1) -> row_of_header #find where rank is
(row_of_header + 1) %>>% (df[.:nrow(df),]) -> df #skip that row and go to the end
names %>>% tolower-> names(df)
}
names(df) %>>% (gsub('\\%|/','\\.',.)) -> names(df)
NULL -> df$rk
c('team','arena') -> table_name_character
df[,!(df %>>% names) %in% table_name_character] %>>%
apply(2, function(x) gsub('\\,','',x) %>>% as.numeric(x)) ->
df[,!(df %>>% names) %in% table_name_character] #get rid of commas and make numeric
df$team %>>% grepl(pattern = '\\*') -> df$playoff_team
df$team %>>% (gsub('\\*','',.)) -> df$team
df %>>% nrow() -1 -> rows
df[1:rows,] -> df
(season_end-1) %>>% paste0("-",season_end) -> season
##Grab Team Ids
url %>>% ## get table
html %>>%
html_nodes(css_id) %>>%
html_attrs() %>>% unlist %>>% as.character -> stems
stems[3:length(stems)] -> stems #skip the 1st 2 rows since they are labels
stems %>>% (gsub('\\/|.html|teams','',.)) %>>% #strip out the text
(gsub(season_end,'',.)) -> bref_team_id #strip out the year to get the team id
data.frame(season,table_name = table, bref_team_id, df) -> df #combine into 1 df
if(date == T){
Sys.time() -> df$scrape_time #add scrape time if you want it
}
return(df)
}
Let’s test it out. Note I auto-populated the function so you can have this year’s team data ready to go without entering parameters. Let’s try it, fingers crossed!
getBREFTeamStatTable() -> team2015
team2015 %>>% kable('html', table.attr='id="team2015"')
season | table_name | bref_team_id | team | g | mp | fg | fga | fg. | X3p | X3pa | X3p. | X2p | X2pa | X2p. | ft | fta | ft. | orb | drb | trb | ast | stl | blk | tov | pf | pts | pts.g | playoff_team | scrape_time |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2014-2015 | team_stats | GSW | Golden State Warriors | 5 | 1200 | 197 | 400 | 0.493 | 47 | 122 | 0.385 | 150 | 278 | 0.540 | 95 | 118 | 0.805 | 45 | 176 | 221 | 124 | 51 | 30 | 108 | 115 | 536 | 107.2 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | DAL | Dallas Mavericks | 6 | 1440 | 250 | 512 | 0.488 | 50 | 139 | 0.360 | 200 | 373 | 0.536 | 89 | 111 | 0.802 | 61 | 172 | 233 | 128 | 44 | 30 | 65 | 116 | 639 | 106.5 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | BOS | Boston Celtics | 6 | 1440 | 252 | 532 | 0.474 | 46 | 150 | 0.307 | 206 | 382 | 0.539 | 88 | 111 | 0.793 | 78 | 188 | 266 | 150 | 47 | 28 | 93 | 133 | 638 | 106.3 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | SAC | Sacramento Kings | 6 | 1490 | 207 | 475 | 0.436 | 23 | 83 | 0.277 | 184 | 392 | 0.469 | 196 | 239 | 0.820 | 74 | 221 | 295 | 106 | 43 | 28 | 104 | 157 | 633 | 105.5 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | TOR | Toronto Raptors | 6 | 1440 | 216 | 500 | 0.432 | 40 | 132 | 0.303 | 176 | 368 | 0.478 | 160 | 207 | 0.773 | 68 | 170 | 238 | 110 | 47 | 28 | 59 | 140 | 632 | 105.3 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | BRK | Brooklyn Nets | 5 | 1200 | 199 | 407 | 0.489 | 47 | 113 | 0.416 | 152 | 294 | 0.517 | 79 | 101 | 0.782 | 44 | 169 | 213 | 98 | 32 | 24 | 72 | 111 | 524 | 104.8 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | CHI | Chicago Bulls | 7 | 1705 | 261 | 548 | 0.476 | 61 | 151 | 0.404 | 200 | 397 | 0.504 | 147 | 193 | 0.762 | 66 | 225 | 291 | 159 | 39 | 46 | 105 | 143 | 730 | 104.3 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | ATL | Atlanta Hawks | 5 | 1250 | 189 | 415 | 0.455 | 50 | 122 | 0.410 | 139 | 293 | 0.474 | 90 | 123 | 0.732 | 42 | 153 | 195 | 124 | 48 | 27 | 74 | 119 | 518 | 103.6 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | LAC | Los Angeles Clippers | 6 | 1440 | 220 | 490 | 0.449 | 50 | 148 | 0.338 | 170 | 342 | 0.497 | 130 | 164 | 0.793 | 49 | 157 | 206 | 136 | 52 | 24 | 70 | 128 | 620 | 103.3 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | PHO | Phoenix Suns | 6 | 1490 | 231 | 514 | 0.449 | 49 | 151 | 0.325 | 182 | 363 | 0.501 | 108 | 136 | 0.794 | 54 | 199 | 253 | 115 | 39 | 33 | 80 | 150 | 619 | 103.2 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | LAL | Los Angeles Lakers | 5 | 1200 | 183 | 423 | 0.433 | 24 | 73 | 0.329 | 159 | 350 | 0.454 | 120 | 158 | 0.759 | 67 | 133 | 200 | 97 | 37 | 19 | 76 | 137 | 510 | 102.0 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | HOU | Houston Rockets | 7 | 1680 | 234 | 527 | 0.444 | 91 | 230 | 0.396 | 143 | 297 | 0.481 | 154 | 215 | 0.716 | 78 | 228 | 306 | 140 | 64 | 34 | 135 | 160 | 713 | 101.9 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | MIA | Miami Heat | 6 | 1440 | 217 | 463 | 0.469 | 51 | 139 | 0.367 | 166 | 324 | 0.512 | 125 | 165 | 0.758 | 57 | 175 | 232 | 136 | 52 | 17 | 88 | 131 | 610 | 101.7 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | POR | Portland Trail Blazers | 6 | 1440 | 223 | 494 | 0.451 | 57 | 162 | 0.352 | 166 | 332 | 0.500 | 98 | 124 | 0.790 | 70 | 210 | 280 | 134 | 30 | 32 | 86 | 131 | 601 | 100.2 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | UTA | Utah Jazz | 6 | 1440 | 220 | 474 | 0.464 | 50 | 155 | 0.323 | 170 | 319 | 0.533 | 108 | 133 | 0.812 | 72 | 179 | 251 | 126 | 35 | 28 | 99 | 115 | 598 | 99.7 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | MIN | Minnesota Timberwolves | 6 | 1465 | 226 | 517 | 0.437 | 29 | 85 | 0.341 | 197 | 432 | 0.456 | 115 | 152 | 0.757 | 81 | 189 | 270 | 123 | 52 | 24 | 88 | 131 | 596 | 99.3 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | CLE | Cleveland Cavaliers | 5 | 1225 | 174 | 415 | 0.419 | 33 | 99 | 0.333 | 141 | 316 | 0.446 | 115 | 140 | 0.821 | 57 | 141 | 198 | 89 | 31 | 16 | 66 | 88 | 496 | 99.2 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | DEN | Denver Nuggets | 5 | 1200 | 178 | 425 | 0.419 | 38 | 131 | 0.290 | 140 | 294 | 0.476 | 101 | 130 | 0.777 | 55 | 153 | 208 | 104 | 24 | 31 | 75 | 141 | 495 | 99.0 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | WAS | Washington Wizards | 7 | 1705 | 257 | 563 | 0.456 | 37 | 110 | 0.336 | 220 | 453 | 0.486 | 132 | 180 | 0.733 | 65 | 225 | 290 | 162 | 65 | 27 | 96 | 167 | 683 | 97.6 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | NOP | New Orleans Pelicans | 5 | 1200 | 186 | 442 | 0.421 | 28 | 99 | 0.283 | 158 | 343 | 0.461 | 86 | 121 | 0.711 | 71 | 164 | 235 | 106 | 39 | 39 | 58 | 105 | 486 | 97.2 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | CHO | Charlotte Hornets | 6 | 1515 | 220 | 502 | 0.438 | 33 | 110 | 0.300 | 187 | 392 | 0.477 | 106 | 145 | 0.731 | 58 | 208 | 266 | 141 | 41 | 32 | 92 | 121 | 579 | 96.5 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | ORL | Orlando Magic | 6 | 1465 | 230 | 504 | 0.456 | 31 | 90 | 0.344 | 199 | 414 | 0.481 | 79 | 114 | 0.693 | 68 | 212 | 280 | 116 | 34 | 32 | 108 | 154 | 570 | 95.0 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | PHI | Philadelphia 76ers | 6 | 1440 | 210 | 484 | 0.434 | 49 | 144 | 0.340 | 161 | 340 | 0.474 | 96 | 149 | 0.644 | 60 | 172 | 232 | 135 | 59 | 38 | 105 | 135 | 565 | 94.2 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | MIL | Milwaukee Bucks | 7 | 1705 | 255 | 585 | 0.436 | 45 | 134 | 0.336 | 210 | 451 | 0.466 | 102 | 130 | 0.785 | 86 | 213 | 299 | 157 | 69 | 42 | 122 | 165 | 657 | 93.9 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | MEM | Memphis Grizzlies | 7 | 1680 | 241 | 560 | 0.430 | 39 | 108 | 0.361 | 202 | 452 | 0.447 | 130 | 165 | 0.788 | 71 | 214 | 285 | 137 | 63 | 20 | 93 | 141 | 651 | 93.0 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | SAS | San Antonio Spurs | 5 | 1200 | 167 | 387 | 0.432 | 34 | 108 | 0.315 | 133 | 279 | 0.477 | 96 | 125 | 0.768 | 54 | 169 | 223 | 100 | 31 | 23 | 91 | 101 | 464 | 92.8 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | IND | Indiana Pacers | 7 | 1705 | 242 | 569 | 0.425 | 55 | 172 | 0.320 | 187 | 397 | 0.471 | 108 | 145 | 0.745 | 87 | 237 | 324 | 131 | 29 | 48 | 123 | 150 | 647 | 92.4 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | NYK | New York Knicks | 7 | 1680 | 253 | 577 | 0.438 | 50 | 120 | 0.417 | 203 | 457 | 0.444 | 88 | 113 | 0.779 | 85 | 196 | 281 | 161 | 40 | 27 | 101 | 173 | 644 | 92.0 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | DET | Detroit Pistons | 5 | 1200 | 170 | 413 | 0.412 | 36 | 110 | 0.327 | 134 | 303 | 0.442 | 80 | 124 | 0.645 | 63 | 164 | 227 | 91 | 22 | 22 | 62 | 106 | 456 | 91.2 | FALSE | 2014-11-09 13:57:02 |
2014-2015 | team_stats | OKC | Oklahoma City Thunder | 6 | 1440 | 201 | 452 | 0.445 | 40 | 126 | 0.317 | 161 | 326 | 0.494 | 101 | 148 | 0.682 | 59 | 201 | 260 | 119 | 32 | 20 | 115 | 137 | 543 | 90.5 | FALSE | 2014-11-09 13:57:02 |
It worked! Now let’s try one last thing to make sure it REALLY works. Lets test another season and different table name. How about the my first season on this earth, the 1983-1984 and the Miscellaneous table.
getBREFTeamStatTable(season_end = 1984,table_name = 'misc',date = F) -> misc1984
misc1984 %>>% kable('html', table.attr='id="misc1984"')
season | table_name | bref_team_id | team | age | pw | pl | mov | sos | srs | ortg | drtg | pace | ftr | X3par | ts. | efg. | tov. | orb. | ft.fga | efg..1 | tov..1 | drb. | ft.fga.1 | arena | attendance | playoff_team |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1983-1984 | misc_stats | BOS | Boston Celtics | 28.0 | 57 | 25 | 6.56 | -0.14 | 6.42 | 110.9 | 104.4 | 99.7 | 0.333 | 0.032 | 0.554 | 0.504 | 14.6 | 34.2 | 0.264 | 0.475 | 13.8 | 69.7 | 0.225 | Boston Garden | 606857 | TRUE |
1983-1984 | misc_stats | MIL | Milwaukee Bucks | 28.4 | 52 | 30 | 4.16 | -0.12 | 4.04 | 107.8 | 103.6 | 96.9 | 0.338 | 0.033 | 0.541 | 0.497 | 15.0 | 33.7 | 0.250 | 0.459 | 14.7 | 65.6 | 0.266 | MECCA Arena | 393301 | TRUE |
1983-1984 | misc_stats | NYK | New York Knicks | 27.2 | 51 | 31 | 3.84 | -0.05 | 3.79 | 107.0 | 103.1 | 99.0 | 0.367 | 0.024 | 0.552 | 0.499 | 16.7 | 33.4 | 0.284 | 0.491 | 17.8 | 68.1 | 0.281 | Madison Square Garden (IV) | 487649 | TRUE |
1983-1984 | misc_stats | DET | Detroit Pistons | 25.4 | 50 | 32 | 3.59 | -0.06 | 3.52 | 111.5 | 108.1 | 103.8 | 0.322 | 0.018 | 0.532 | 0.482 | 12.7 | 36.7 | 0.250 | 0.500 | 14.8 | 67.7 | 0.263 | Pontiac Silverdome | 652865 | TRUE |
1983-1984 | misc_stats | LAL | Los Angeles Lakers | 27.5 | 50 | 32 | 3.76 | -0.44 | 3.32 | 110.9 | 107.3 | 103.7 | 0.313 | 0.031 | 0.574 | 0.536 | 16.1 | 33.7 | 0.236 | 0.487 | 14.3 | 66.6 | 0.232 | The Forum | 622401 | TRUE |
1983-1984 | misc_stats | POR | Portland Trail Blazers | 25.8 | 50 | 32 | 3.55 | -0.42 | 3.13 | 111.2 | 107.7 | 101.1 | 0.367 | 0.018 | 0.556 | 0.507 | 15.1 | 36.4 | 0.277 | 0.518 | 17.0 | 67.4 | 0.259 | Memorial Coliseum | 518306 | TRUE |
1983-1984 | misc_stats | PHI | Philadelphia 76ers | 27.7 | 47 | 35 | 2.20 | 0.20 | 2.39 | 106.8 | 104.6 | 99.6 | 0.396 | 0.016 | 0.551 | 0.497 | 16.9 | 34.6 | 0.299 | 0.484 | 16.0 | 65.9 | 0.246 | The Spectrum | 588139 | TRUE |
1983-1984 | misc_stats | NJN | New Jersey Nets | 25.5 | 44 | 38 | 1.10 | 0.17 | 1.27 | 106.1 | 105.0 | 103.0 | 0.343 | 0.032 | 0.540 | 0.501 | 16.1 | 34.6 | 0.240 | 0.494 | 17.0 | 67.8 | 0.292 | Brendan Byrne Arena | 499496 | TRUE |
1983-1984 | misc_stats | UTA | Utah Jazz | 26.8 | 44 | 38 | 1.13 | -0.32 | 0.81 | 109.0 | 108.0 | 104.9 | 0.374 | 0.044 | 0.559 | 0.505 | 15.2 | 30.8 | 0.292 | 0.479 | 13.9 | 63.4 | 0.229 | Salt Palace | 400065 | TRUE |
1983-1984 | misc_stats | PHO | Phoenix Suns | 27.2 | 43 | 39 | 0.89 | -0.24 | 0.65 | 108.9 | 108.0 | 101.4 | 0.305 | 0.040 | 0.556 | 0.514 | 15.1 | 31.4 | 0.232 | 0.501 | 15.3 | 68.3 | 0.277 | Arizona Veterans Memorial Coliseum | 445788 | TRUE |
1983-1984 | misc_stats | DAL | Dallas Mavericks | 24.7 | 42 | 40 | 0.43 | -0.27 | 0.15 | 110.0 | 109.6 | 99.0 | 0.325 | 0.025 | 0.547 | 0.503 | 13.6 | 31.7 | 0.245 | 0.503 | 14.4 | 65.7 | 0.232 | Reunion Arena | 538162 | TRUE |
1983-1984 | misc_stats | SEA | Seattle SuperSonics | 27.1 | 41 | 41 | -0.17 | -0.17 | -0.34 | 107.9 | 108.1 | 99.7 | 0.347 | 0.020 | 0.543 | 0.490 | 14.3 | 30.7 | 0.271 | 0.492 | 13.8 | 66.6 | 0.226 | King County Domed Stadium | 425307 | TRUE |
1983-1984 | misc_stats | SAS | San Antonio Spurs | 27.4 | 40 | 42 | -0.27 | -0.23 | -0.50 | 111.2 | 111.4 | 106.5 | 0.337 | 0.034 | 0.556 | 0.511 | 14.0 | 33.4 | 0.255 | 0.508 | 13.7 | 66.2 | 0.233 | HemisFair Arena | 375900 | FALSE |
1983-1984 | misc_stats | ATL | Atlanta Hawks | 26.6 | 37 | 45 | -1.29 | 0.22 | -1.08 | 105.5 | 106.9 | 95.3 | 0.355 | 0.016 | 0.529 | 0.476 | 14.4 | 31.6 | 0.270 | 0.482 | 15.1 | 65.2 | 0.268 | Omni Coliseum | 286049 | TRUE |
1983-1984 | misc_stats | DEN | Denver Nuggets | 27.0 | 38 | 44 | -1.10 | -0.17 | -1.27 | 111.3 | 112.3 | 110.5 | 0.337 | 0.032 | 0.553 | 0.498 | 12.8 | 29.3 | 0.276 | 0.522 | 14.6 | 66.6 | 0.277 | McNichols Sports Arena | 462407 | TRUE |
1983-1984 | misc_stats | KCK | Kansas City Kings | 26.2 | 37 | 45 | -1.48 | -0.15 | -1.62 | 106.5 | 108.0 | 102.9 | 0.345 | 0.026 | 0.542 | 0.490 | 15.3 | 32.4 | 0.268 | 0.505 | 16.1 | 66.9 | 0.266 | Kemper Arena | 370270 | TRUE |
1983-1984 | misc_stats | WSB | Washington Bullets | 26.2 | 33 | 49 | -2.89 | 0.53 | -2.36 | 104.2 | 107.2 | 97.4 | 0.319 | 0.041 | 0.535 | 0.489 | 15.5 | 30.1 | 0.241 | 0.492 | 13.7 | 69.7 | 0.239 | Capital Centre | 317447 | TRUE |
1983-1984 | misc_stats | HOU | Houston Rockets | 26.8 | 33 | 49 | -3.09 | -0.04 | -3.12 | 105.3 | 108.2 | 104.7 | 0.284 | 0.020 | 0.535 | 0.497 | 15.6 | 32.8 | 0.210 | 0.486 | 14.1 | 67.5 | 0.285 | The Summit | 425755 | FALSE |
1983-1984 | misc_stats | SDC | San Diego Clippers | 25.5 | 33 | 49 | -3.26 | 0.04 | -3.21 | 109.2 | 112.4 | 101.1 | 0.331 | 0.017 | 0.541 | 0.498 | 15.3 | 37.7 | 0.244 | 0.513 | 12.9 | 68.2 | 0.236 | San Diego Sports Arena | 218534 | FALSE |
1983-1984 | misc_stats | GSW | Golden State Warriors | 25.6 | 32 | 50 | -3.40 | 0.05 | -3.35 | 105.5 | 108.8 | 103.3 | 0.342 | 0.030 | 0.520 | 0.471 | 14.9 | 35.6 | 0.254 | 0.519 | 17.0 | 64.2 | 0.250 | Oakland-Alameda County Coliseum Arena | 316844 | FALSE |
1983-1984 | misc_stats | CLE | Cleveland Cavaliers | 25.4 | 30 | 52 | -4.26 | 0.55 | -3.71 | 104.1 | 108.5 | 97.4 | 0.301 | 0.023 | 0.512 | 0.468 | 14.0 | 33.5 | 0.224 | 0.490 | 13.2 | 70.8 | 0.280 | Coliseum at Richfield | 208094 | FALSE |
1983-1984 | misc_stats | IND | Indiana Pacers | 24.4 | 28 | 54 | -4.82 | 0.57 | -4.25 | 101.8 | 106.5 | 102.1 | 0.297 | 0.029 | 0.531 | 0.487 | 15.9 | 28.1 | 0.228 | 0.497 | 16.2 | 66.8 | 0.255 | Market Square Arena | 410626 | FALSE |
1983-1984 | misc_stats | CHI | Chicago Bulls | 24.4 | 28 | 54 | -5.18 | 0.50 | -4.69 | 102.4 | 107.5 | 99.8 | 0.360 | 0.017 | 0.526 | 0.475 | 16.3 | 32.3 | 0.268 | 0.497 | 15.6 | 67.2 | 0.266 | Chicago Stadium | 256430 | FALSE |
Hope you found this tutorial fun, enlightening, and fairly easy to follow. Please feel free to peruse the source code and ABSOLUTELY make use of the function we created however you please. For my next post I will use our beautiful new function to create a few interactive data visualizations and explore some quiche algorithms that may help you see data in a new and even more empowering light. Until then stay keep on keeping on and, as always, have any questions or comments feel free to reach out to me on twitter.