Introduction

This analysis looks at batting statistics for the New York Mets from 1962-2023, sourced from Kaggle: [New York Mets Batting & Pitching (1962-2023)] (https://www.kaggle.com/datasets/mattop/new-york-mets-batting-and-pitching-1962-2023/data). The goal is to build a clean, analysis-ready data frame from the raw batting data, with meaningful column names and positions spelled out in full.

library(readr)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# Load the raw Mets batting data from GitHub 
mets_batting <- read_csv("https://raw.githubusercontent.com/nowhyporque/data607DataAcquisitionAndManagement/refs/heads/main/Assignment1/NYM_batting.csv")
## Rows: 2728 Columns: 31
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (4): Position, Name, Dominant_Hand, Switch_Hitter
## dbl (27): Rank, Year, Age, Games, Plate_Appearances, At_Bats, Runs, Hits, Do...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
glimpse(mets_batting)
## Rows: 2,728
## Columns: 31
## $ Rank                                  <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1…
## $ Year                                  <dbl> 2023, 2023, 2023, 2023, 2023, 20…
## $ Position                              <chr> "C", "1B", "2B", "SS", "3B", "LF…
## $ Name                                  <chr> "Francisco Álvarez", "Pete Alons…
## $ Age                                   <dbl> 21, 28, 31, 29, 23, 34, 30, 34, …
## $ Games                                 <dbl> 123, 154, 156, 160, 108, 89, 152…
## $ Plate_Appearances                     <dbl> 423, 658, 648, 687, 389, 303, 68…
## $ At_Bats                               <dbl> 382, 568, 585, 602, 353, 257, 59…
## $ Runs                                  <dbl> 51, 92, 75, 108, 41, 28, 89, 38,…
## $ Hits                                  <dbl> 80, 123, 158, 153, 75, 63, 162, …
## $ Doubles                               <dbl> 12, 21, 25, 33, 12, 15, 30, 7, 8…
## $ Triples                               <dbl> 0, 2, 4, 2, 0, 1, 6, 1, 0, 1, 1,…
## $ Home_Runs                             <dbl> 25, 46, 10, 31, 9, 6, 24, 5, 13,…
## $ Runs_Batted_In                        <dbl> 63, 118, 55, 98, 34, 29, 68, 28,…
## $ Stolen_Bases                          <dbl> 2, 4, 10, 31, 2, 7, 3, 24, 0, 11…
## $ Caught_Stealing                       <dbl> 0, 1, 0, 4, 0, 0, 3, 4, 0, 1, 0,…
## $ Base_On_Balls                         <dbl> 34, 65, 39, 66, 29, 32, 74, 16, …
## $ Strikeouts                            <dbl> 110, 151, 65, 137, 109, 52, 146,…
## $ Batting_Average                       <dbl> 0.209, 0.217, 0.270, 0.254, 0.21…
## $ On_Base_Percentage                    <dbl> 0.284, 0.318, 0.333, 0.336, 0.27…
## $ Slugging_Percentage                   <dbl> 0.437, 0.504, 0.378, 0.470, 0.32…
## $ On_Base_Plus_Slugging_Percentage      <dbl> 0.721, 0.821, 0.711, 0.806, 0.59…
## $ On_Base_Plus_Slugging_Percentage_Plus <dbl> 95, 122, 96, 120, 65, 100, 127, …
## $ Total_Bases                           <dbl> 167, 286, 221, 283, 114, 98, 276…
## $ Double_Plays_Grounded_Into            <dbl> 14, 17, 5, 8, 8, 8, 6, 8, 6, 2, …
## $ Times_Hit_By_Pitch                    <dbl> 6, 21, 18, 12, 2, 9, 11, 8, 2, 1…
## $ Sacrifice_Hits                        <dbl> 0, 0, 3, 0, 1, 0, 1, 2, 0, 0, 0,…
## $ Sacrifice_Flies                       <dbl> 1, 4, 3, 7, 1, 5, 4, 0, 0, 3, 2,…
## $ Intentional_Bases_on_Balls            <dbl> 0, 6, 0, 1, 0, 0, 0, 1, 1, 1, 0,…
## $ Dominant_Hand                         <chr> "Right", "Right", "Left", "Right…
## $ Switch_Hitter                         <chr> "No", "No", "No", "Yes", "No", "…
# Lookup table to translate abbreviated position codes into full names
position_lookup <- c(
  "C" = "Catcher", "1B" = "First Base", "2B" = "Second Base",
  "3B" = "Third Base", "SS" = "Shortstop", "LF" = "Left Field",
  "CF" = "Center Field", "RF" = "Right Field", "DH" = "Designated Hitter",
  "OF" = "Outfield", "P" = "Pitcher"
)

# Add the full position name, then narrow down to the columns relevant
# for analyzing the player performance
mets_clean <- mets_batting %>%
  mutate(Position_Full = recode(Position, !!!position_lookup)) %>%
  select(Year, Name, Position, Position_Full, Age, Games,
         At_Bats, Hits, Home_Runs, Runs_Batted_In)
glimpse(mets_clean)
## Rows: 2,728
## Columns: 10
## $ Year           <dbl> 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2…
## $ Name           <chr> "Francisco Álvarez", "Pete Alonso", "Jeff McNeil", "Fra…
## $ Position       <chr> "C", "1B", "2B", "SS", "3B", "LF", "CF", "RF", "DH", "L…
## $ Position_Full  <chr> "Catcher", "First Base", "Second Base", "Shortstop", "T…
## $ Age            <dbl> 21, 28, 31, 29, 23, 34, 30, 34, 30, 35, 23, 29, 31, 32,…
## $ Games          <dbl> 123, 154, 156, 160, 108, 89, 152, 86, 104, 79, 65, 58, …
## $ At_Bats        <dbl> 382, 568, 585, 602, 353, 257, 592, 315, 275, 231, 218, …
## $ Hits           <dbl> 80, 123, 158, 153, 75, 63, 162, 78, 64, 62, 46, 39, 27,…
## $ Home_Runs      <dbl> 25, 46, 10, 31, 9, 6, 24, 5, 13, 10, 9, 11, 2, 1, 1, 4,…
## $ Runs_Batted_In <dbl> 63, 118, 55, 98, 34, 29, 68, 28, 48, 36, 22, 26, 7, 8, …

Conclusions

The cleaned data frame narrows the original 31 columns down to 10 relevant fields for analyzing player performance, with Home_Runs as a natural target variable. Future work could join this with the pitching dataset, add advanced metrics like OBP or SLG, or compare performance across different Mets eras (e.g. 1962-1969 vs. the current roster).