Okay, let's see if we can use Julia for some sabermetrics.
First, head on over to juliabox.org and register. I have a secret code.
We need to add on some external packages. Sadly these can be a bit slow to load, so let's do it know:
using Gadfly, DataFrames
(These are pre-installed on juliabox.)
f = "http://seanlahman.com/files/database/lahman-csv_2015-01-24.zip" d = "/tmp/lahman" if !isdir(d) mkdir(d) fout = "$d/lahman-csv.zip" download(f, fout) run(`unzip -n -d $d $fout`) end
Julia had a DataFrame type to hold tabular data. (Akin to Python's Pandas or R's data.frame types.) We can use readtable to read a csv file into a data frame
d = readtable("$d/Batting.csv")
| playerID | yearID | stint | teamID | lgID | G | AB | R | H | x2B | x3B | HR | RBI | SB | CS | BB | SO | IBB | HBP | SH | SF | GIDP | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | abercda01 | 1871 | 1 | TRO | NA | 1 | 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NA | NA | NA | NA | NA |
| 2 | addybo01 | 1871 | 1 | RC1 | NA | 25 | 118 | 30 | 32 | 6 | 0 | 0 | 13 | 8 | 1 | 4 | 0 | NA | NA | NA | NA | NA |
| 3 | allisar01 | 1871 | 1 | CL1 | NA | 29 | 137 | 28 | 40 | 4 | 5 | 0 | 19 | 3 | 1 | 2 | 5 | NA | NA | NA | NA | NA |
| 4 | allisdo01 | 1871 | 1 | WS3 | NA | 27 | 133 | 28 | 44 | 10 | 2 | 2 | 27 | 1 | 1 | 0 | 2 | NA | NA | NA | NA | NA |
| 5 | ansonca01 | 1871 | 1 | RC1 | NA | 25 | 120 | 29 | 39 | 11 | 3 | 0 | 16 | 6 | 2 | 2 | 1 | NA | NA | NA | NA | NA |
| 6 | armstbo01 | 1871 | 1 | FW1 | NA | 12 | 49 | 9 | 11 | 2 | 1 | 0 | 5 | 0 | 1 | 0 | 1 | NA | NA | NA | NA | NA |
| 7 | barkeal01 | 1871 | 1 | RC1 | NA | 1 | 4 | 0 | 1 | 0 | 0 | 0 | 2 | 0 | 0 | 1 | 0 | NA | NA | NA | NA | NA |
| 8 | barnero01 | 1871 | 1 | BS1 | NA | 31 | 157 | 66 | 63 | 10 | 9 | 0 | 34 | 11 | 6 | 13 | 1 | NA | NA | NA | NA | NA |
| 9 | barrebi01 | 1871 | 1 | FW1 | NA | 1 | 5 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | NA | NA | NA | NA | NA |
| 10 | barrofr01 | 1871 | 1 | BS1 | NA | 18 | 86 | 13 | 13 | 2 | 1 | 0 | 11 | 1 | 0 | 0 | 0 | NA | NA | NA | NA | NA |
| 11 | bassjo01 | 1871 | 1 | CL1 | NA | 22 | 89 | 18 | 27 | 1 | 10 | 3 | 18 | 0 | 1 | 3 | 4 | NA | NA | NA | NA | NA |
| 12 | battijo01 | 1871 | 1 | CL1 | NA | 1 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | NA | NA | NA | NA | NA |
| 13 | bealsto01 | 1871 | 1 | WS3 | NA | 10 | 36 | 6 | 7 | 0 | 0 | 0 | 1 | 2 | 0 | 2 | 0 | NA | NA | NA | NA | NA |
| 14 | beaveed01 | 1871 | 1 | TRO | NA | 3 | 15 | 7 | 6 | 0 | 0 | 0 | 5 | 2 | 0 | 0 | 0 | NA | NA | NA | NA | NA |
| 15 | bechtge01 | 1871 | 1 | PH1 | NA | 20 | 94 | 24 | 33 | 9 | 1 | 1 | 21 | 4 | 0 | 2 | 2 | NA | NA | NA | NA | NA |
| 16 | bellast01 | 1871 | 1 | TRO | NA | 29 | 128 | 26 | 32 | 3 | 3 | 0 | 23 | 4 | 4 | 9 | 2 | NA | NA | NA | NA | NA |
| 17 | berkena01 | 1871 | 1 | PH1 | NA | 1 | 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | NA | NA | NA | NA | NA |
| 18 | berryto01 | 1871 | 1 | PH1 | NA | 1 | 4 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NA | NA | NA | NA | NA |
| 19 | berthha01 | 1871 | 1 | WS3 | NA | 17 | 73 | 17 | 17 | 1 | 1 | 0 | 8 | 3 | 1 | 4 | 2 | NA | NA | NA | NA | NA |
| 20 | biermch01 | 1871 | 1 | FW1 | NA | 1 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | NA | NA | NA | NA | NA |
| 21 | birdge01 | 1871 | 1 | RC1 | NA | 25 | 106 | 19 | 28 | 2 | 5 | 0 | 13 | 1 | 0 | 3 | 2 | NA | NA | NA | NA | NA |
| 22 | birdsda01 | 1871 | 1 | BS1 | NA | 29 | 152 | 51 | 46 | 3 | 3 | 0 | 24 | 6 | 0 | 4 | 4 | NA | NA | NA | NA | NA |
| 23 | brainas01 | 1871 | 1 | WS3 | NA | 30 | 134 | 24 | 30 | 4 | 0 | 0 | 21 | 4 | 0 | 7 | 2 | NA | NA | NA | NA | NA |
| 24 | brannmi01 | 1871 | 1 | CH1 | NA | 3 | 14 | 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NA | NA | NA | NA | NA |
| 25 | burrohe01 | 1871 | 1 | WS3 | NA | 12 | 63 | 11 | 15 | 2 | 3 | 1 | 14 | 0 | 0 | 1 | 1 | NA | NA | NA | NA | NA |
| 26 | careyto01 | 1871 | 1 | FW1 | NA | 19 | 87 | 16 | 20 | 2 | 0 | 0 | 10 | 5 | 0 | 2 | 1 | NA | NA | NA | NA | NA |
| 27 | carleji01 | 1871 | 1 | CL1 | NA | 29 | 127 | 31 | 32 | 8 | 1 | 0 | 18 | 2 | 1 | 8 | 3 | NA | NA | NA | NA | NA |
| 28 | conefr01 | 1871 | 1 | BS1 | NA | 19 | 77 | 17 | 20 | 3 | 1 | 0 | 16 | 12 | 1 | 8 | 2 | NA | NA | NA | NA | NA |
| 29 | connone01 | 1871 | 1 | TRO | NA | 7 | 33 | 6 | 7 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | NA | NA | NA | NA | NA |
| 30 | cravebi01 | 1871 | 1 | TRO | NA | 27 | 118 | 26 | 38 | 8 | 1 | 0 | 26 | 6 | 3 | 3 | 0 | NA | NA | NA | NA | NA |
| ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
Data frames store variables in columns. To access a single column we use the notation d[:name]. The : makes the name a symbol. This works fine unless there are spaces in the names, in which case use :(name with spaces) as a pattern.
d[:RBI]
99846-element DataArray{Int64,1}:
0
13
19
27
16
5
2
34
1
11
18
0
1
⋮
13
0
28
10
30
17
0
0
1
38
52
60
There are values with no RBI info. These are stored as NA (not 0). To see them we need to
Indexing of d can be done by column (as above) or by row and column. The notation is d[rowindex,columnindex].
The row index can be specified by number (1 or by range 1:3 or by vector [1,3,5], use : to refer to all of them). Similarly the column index.
More commonly we can index by a logical vector with a length that matches the number of rows. These are generated by logical operators or by special "is" functions, as here with isna:
d[isna(d[:RBI]), :yearID]
5573-element DataArray{Int64,1}:
1882
1882
1882
1882
1882
1882
1882
1882
1882
1882
1882
1882
1882
⋮
1999
1999
1999
1999
1999
1999
1999
1999
1999
1999
1999
1999
We see the early years, but also some in 1999. What happened there?
d[(isna(d[:RBI])) & (d[:yearID] .== 1999), :]
| playerID | yearID | stint | teamID | lgID | G | AB | R | H | x2B | x3B | HR | RBI | SB | CS | BB | SO | IBB | HBP | SH | SF | GIDP | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | aguilri01 | 1999 | 1 | MIN | AL | 17 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 2 | alvarju01 | 1999 | 1 | ANA | AL | 8 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 3 | anderma01 | 1999 | 1 | DET | AL | 37 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 4 | appieke01 | 1999 | 2 | OAK | AL | 12 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 5 | arrojro01 | 1999 | 1 | TBA | AL | 24 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 6 | balejo01 | 1999 | 1 | TOR | AL | 1 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 7 | bradfch01 | 1999 | 1 | CHA | AL | 3 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 8 | broweji01 | 1999 | 1 | CLE | AL | 9 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 9 | brunswi01 | 1999 | 1 | DET | AL | 17 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 10 | buddimi01 | 1999 | 1 | NYA | AL | 2 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 11 | bunchme01 | 1999 | 1 | SEA | AL | 5 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 12 | candito01 | 1999 | 1 | OAK | AL | 11 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 13 | cartela02 | 1999 | 1 | KCA | AL | 6 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 14 | castica02 | 1999 | 1 | CHA | AL | 18 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 15 | coopebr01 | 1999 | 1 | ANA | AL | 5 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 16 | cordefr01 | 1999 | 1 | DET | AL | 20 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 17 | corsiji01 | 1999 | 2 | BAL | AL | 13 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 18 | daveyto01 | 1999 | 2 | SEA | AL | 16 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 19 | davisdo02 | 1999 | 1 | TEX | AL | 2 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 20 | delucri01 | 1999 | 1 | CLE | AL | 6 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 21 | depause01 | 1999 | 1 | CLE | AL | 11 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 22 | durbich01 | 1999 | 1 | KCA | AL | 1 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 23 | falkebr01 | 1999 | 1 | BAL | AL | 2 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 24 | fasseje01 | 1999 | 2 | TEX | AL | 7 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 25 | fettemi01 | 1999 | 1 | BAL | AL | 27 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 26 | floribr01 | 1999 | 2 | BOS | AL | 14 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 27 | fossato01 | 1999 | 1 | NYA | AL | 5 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 28 | frankry01 | 1999 | 1 | SEA | AL | 6 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 29 | fussech01 | 1999 | 1 | KCA | AL | 17 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 30 | gailled01 | 1999 | 1 | TBA | AL | 8 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
I'm guessing American League pitchers with no atbats.
That syntax is pretty clunky. You need to put the expressions in (), and use .== instead of just == to get comparison as we are comparing each element of d[:yearID] to 1999. The DataFramesMeta package can make it easier. We have to install this one thoughL
Pkg.add("DataFramesMeta")
using DataFramesMeta
Then the above becomes something like:
@linq d |> where(isna(:RBI)) |> where(:yearID .== 1999)
| playerID | yearID | stint | teamID | lgID | G | AB | R | H | x2B | x3B | HR | RBI | SB | CS | BB | SO | IBB | HBP | SH | SF | GIDP | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | aguilri01 | 1999 | 1 | MIN | AL | 17 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 2 | alvarju01 | 1999 | 1 | ANA | AL | 8 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 3 | anderma01 | 1999 | 1 | DET | AL | 37 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 4 | appieke01 | 1999 | 2 | OAK | AL | 12 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 5 | arrojro01 | 1999 | 1 | TBA | AL | 24 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 6 | balejo01 | 1999 | 1 | TOR | AL | 1 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 7 | bradfch01 | 1999 | 1 | CHA | AL | 3 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 8 | broweji01 | 1999 | 1 | CLE | AL | 9 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 9 | brunswi01 | 1999 | 1 | DET | AL | 17 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 10 | buddimi01 | 1999 | 1 | NYA | AL | 2 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 11 | bunchme01 | 1999 | 1 | SEA | AL | 5 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 12 | candito01 | 1999 | 1 | OAK | AL | 11 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 13 | cartela02 | 1999 | 1 | KCA | AL | 6 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 14 | castica02 | 1999 | 1 | CHA | AL | 18 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 15 | coopebr01 | 1999 | 1 | ANA | AL | 5 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 16 | cordefr01 | 1999 | 1 | DET | AL | 20 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 17 | corsiji01 | 1999 | 2 | BAL | AL | 13 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 18 | daveyto01 | 1999 | 2 | SEA | AL | 16 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 19 | davisdo02 | 1999 | 1 | TEX | AL | 2 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 20 | delucri01 | 1999 | 1 | CLE | AL | 6 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 21 | depause01 | 1999 | 1 | CLE | AL | 11 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 22 | durbich01 | 1999 | 1 | KCA | AL | 1 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 23 | falkebr01 | 1999 | 1 | BAL | AL | 2 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 24 | fasseje01 | 1999 | 2 | TEX | AL | 7 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 25 | fettemi01 | 1999 | 1 | BAL | AL | 27 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 26 | floribr01 | 1999 | 2 | BOS | AL | 14 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 27 | fossato01 | 1999 | 1 | NYA | AL | 5 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 28 | frankry01 | 1999 | 1 | SEA | AL | 6 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 29 | fussech01 | 1999 | 1 | KCA | AL | 17 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 30 | gailled01 | 1999 | 1 | TBA | AL | 8 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
Okay, let's get at some anomalies. Which players have the most home runs?
The data is stored by player so we need to split up the data by each player and add up the :HR values. When we split the data, we will get a smaller data frame. This function will add up the HRs ( paying attention to NA values):
function add_hrs(d) hrs = d[:HR] hrs = hrs[!isna(hrs)] sum(hrs) end
add_hrs (generic function with 1 method)
Here we split the data and apply the function
a = by(d, :playerID, add_hrs)
| playerID | x1 | |
|---|---|---|
| 1 | aardsda01 | 0 |
| 2 | aaronha01 | 755 |
| 3 | aaronto01 | 13 |
| 4 | aasedo01 | 0 |
| 5 | abadan01 | 0 |
| 6 | abadfe01 | 0 |
| 7 | abadijo01 | 0 |
| 8 | abbated01 | 11 |
| 9 | abbeybe01 | 0 |
| 10 | abbeych01 | 19 |
| 11 | abbotda01 | 0 |
| 12 | abbotfr01 | 1 |
| 13 | abbotgl01 | 0 |
| 14 | abbotje01 | 18 |
| 15 | abbotji01 | 0 |
| 16 | abbotku01 | 62 |
| 17 | abbotky01 | 0 |
| 18 | abbotod01 | 0 |
| 19 | abbotpa01 | 0 |
| 20 | aberal01 | 0 |
| 21 | abercda01 | 0 |
| 22 | abercre01 | 9 |
| 23 | abernbi01 | 0 |
| 24 | abernbr01 | 8 |
| 25 | abernte01 | 0 |
| 26 | abernte02 | 0 |
| 27 | abernwo01 | 0 |
| 28 | aberscl01 | 5 |
| 29 | ablesha01 | 0 |
| 30 | abnersh01 | 11 |
| ⋮ | ⋮ | ⋮ |
We want to sort by the numbers. We can sort as follows:
sort(a[:x1])
18405-element DataArray{Int64,1}:
0
0
0
0
0
0
0
0
0
0
0
0
0
⋮
569
573
583
586
609
612
630
654
660
714
755
762
But to sort the data frame we want to shuffle the items around. The sortperm function helps here. It returns the indices of the permutation that will sort the data. Here we pass in rev=true to get reverse order:
a[sortperm(a[:x1], rev=true),:]
| playerID | x1 | |
|---|---|---|
| 1 | bondsba01 | 762 |
| 2 | aaronha01 | 755 |
| 3 | ruthba01 | 714 |
| 4 | mayswi01 | 660 |
| 5 | rodrial01 | 654 |
| 6 | griffke02 | 630 |
| 7 | thomeji01 | 612 |
| 8 | sosasa01 | 609 |
| 9 | robinfr02 | 586 |
| 10 | mcgwima01 | 583 |
| 11 | killeha01 | 573 |
| 12 | palmera01 | 569 |
| 13 | jacksre01 | 563 |
| 14 | ramirma02 | 555 |
| 15 | schmimi01 | 548 |
| 16 | mantlmi01 | 536 |
| 17 | foxxji01 | 534 |
| 18 | mccovwi01 | 521 |
| 19 | thomafr04 | 521 |
| 20 | willite01 | 521 |
| 21 | pujolal01 | 520 |
| 22 | bankser01 | 512 |
| 23 | matheed01 | 512 |
| 24 | ottme01 | 511 |
| 25 | sheffga01 | 509 |
| 26 | murraed02 | 504 |
| 27 | gehrilo01 | 493 |
| 28 | mcgrifr01 | 493 |
| 29 | musiast01 | 475 |
| 30 | stargwi01 | 475 |
| ⋮ | ⋮ | ⋮ |
Go Bonds!
What function will compute the on base percentage?
$$ OBP = \frac{H + BB + HBP}{AB + BB + HBP + SF} $$
Do we have these in the data?
names(d)
22-element Array{Symbol,1}:
:playerID
:yearID
:stint
:teamID
:lgID
:G
:AB
:R
:H
:x2B
:x3B
:HR
:RBI
:SB
:CS
:BB
:SO
:IBB
:HBP
:SH
:SF
:GIDP
We are good to go. Here we define a function to compute the OBP. The only issue is the NA values must be addressed and those who barely played are weeded out (and given a 0.0 value)
function compute_obp(d)
u = d[:, [:H, :BB, :HBP, :AB, :SF]]
## make NA -> 0
for nm in names(u)
u[isna(u[nm]), nm] = 0
end
sum(u[:AB]) > 100 || return(0.0)
top = @with(u, :H + :BB + :HBP)
bottom = @with(u, :AB + :BB + :HBP + :SF)
sum(top) / sum(bottom)
end
compute_obp (generic function with 1 method)
The pattern is as before:
OBP = by(d, :playerID, compute_obp) OBP = OBP[sortperm(OBP[:x1], rev=true), :]
| playerID | x1 | |
|---|---|---|
| 1 | willite01 | 0.48170856325362765 |
| 2 | ruthba01 | 0.4739598210035228 |
| 3 | mcgrajo01 | 0.4656722517368206 |
| 4 | hamilbi01 | 0.4551961823966066 |
| 5 | gehrilo01 | 0.44735189449445256 |
| 6 | bondsba01 | 0.44429455641961596 |
| 7 | joycebi01 | 0.4348668280871671 |
| 8 | hornsro01 | 0.43374014472405226 |
| 9 | cobbty01 | 0.4329654848555999 |
| 10 | foxxji01 | 0.42827377851859566 |
| 11 | speaktr01 | 0.4279475982532751 |
| 12 | smithol01 | 0.4268292682926829 |
| 13 | collied01 | 0.4243817787418655 |
| 14 | fainfe01 | 0.42407407407407405 |
| 15 | broutda01 | 0.42332810867293624 |
| 16 | jacksjo01 | 0.42273790250044974 |
| 17 | bishoma01 | 0.4226840436773512 |
| 18 | mantlmi01 | 0.42051541182415364 |
| 19 | wardpi01 | 0.4191866527632951 |
| 20 | cochrmi01 | 0.41915772089182496 |
| 21 | thomafr04 | 0.41909866984316063 |
| 22 | martied01 | 0.41780189332717615 |
| 23 | vottojo01 | 0.4172821270310192 |
| 24 | musiast01 | 0.41666009308195945 |
| 25 | bassljo01 | 0.41612436731742586 |
| 26 | childcu01 | 0.4157673860911271 |
| 27 | burkeje01 | 0.41511811023622047 |
| 28 | boggswa01 | 0.41499393147231817 |
| 29 | pottsjo01 | 0.4140625 |
| 30 | heltoto01 | 0.41399386048481 |
| ⋮ | ⋮ | ⋮ |