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 |
⋮ | ⋮ | ⋮ |