Introduction

This report uses data downloaded from ???.

Read the data

Per game

Read the file:

df_per_game <- read_csv(
  './data/2022-12-27-per-player-per-game.csv'
) %>% 
  clean_names() %>% 
  remove_empty(quiet = FALSE) %>% 
  remove_constant(quiet = FALSE)
## value for "which" not specified, defaulting to c("rows", "cols")
## Rows: 812 Columns: 31
## ── Column specification ─────────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (4): Player, Pos, Tm, Player-additional
## dbl (27): Rk, Age, G, GS, MP, FG, FGA, FG%, 3P, 3PA, 3P%, 2P, 2PA, 2P%, eFG%, FT,...
## 
## ℹ 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.
## No empty rows to remove.
## 
## No empty columns to remove.
## 
## No constant columns to remove.

First look at the data:

df_per_game %>% glimpse()
## Rows: 812
## Columns: 31
## $ rk                <dbl> 1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 9, 10, 10, 10, 11, 12, 13, …
## $ player            <chr> "Precious Achiuwa", "Steven Adams", "Bam Adebayo", "Santi…
## $ pos               <chr> "C", "C", "C", "PF", "C", "SG", "SG", "SG", "SG", "C", "P…
## $ age               <dbl> 22, 28, 24, 21, 36, 23, 23, 23, 26, 23, 23, 28, 28, 28, 2…
## $ tm                <chr> "TOR", "MEM", "MIA", "MEM", "BRK", "TOT", "NOP", "UTA", "…
## $ g                 <dbl> 73, 76, 56, 32, 47, 65, 50, 15, 66, 56, 54, 16, 3, 13, 69…
## $ gs                <dbl> 28, 75, 56, 0, 12, 21, 19, 2, 61, 56, 1, 6, 0, 6, 11, 67,…
## $ mp                <dbl> 23,6, 26,3, 32,6, 11,3, 22,3, 22,6, 26,3, 9,9, 27,3, 32,3…
## $ fg                <dbl> 3,6, 2,8, 7,3, 1,7, 5,4, 3,9, 4,7, 1,1, 3,9, 6,6, 2,4, 2,…
## $ fga               <dbl> 8,3, 5,1, 13,0, 4,1, 9,7, 10,5, 12,6, 3,2, 8,6, 9,7, 5,4,…
## $ fg_percent        <dbl> 0,439, 0,547, 0,557, 0,402, 0,550, 0,372, 0,375, 0,333, 0…
## $ x3p               <dbl> 0,8, 0,0, 0,0, 0,2, 0,3, 1,6, 1,9, 0,7, 2,4, 0,0, 0,6, 0,…
## $ x3pa              <dbl> 2,1, 0,0, 0,1, 1,5, 1,0, 5,2, 6,1, 2,2, 5,9, 0,2, 2,0, 3,…
## $ x3p_percent       <dbl> 0,359, 0,000, 0,000, 0,125, 0,304, 0,311, 0,311, 0,303, 0…
## $ x2p               <dbl> 2,9, 2,8, 7,3, 1,5, 5,1, 2,3, 2,8, 0,4, 1,5, 6,6, 1,8, 1,…
## $ x2pa              <dbl> 6,1, 5,0, 12,9, 2,6, 8,8, 5,3, 6,5, 1,0, 2,7, 9,6, 3,4, 2…
## $ x2p_percent       <dbl> 0,468, 0,548, 0,562, 0,560, 0,578, 0,433, 0,434, 0,400, 0…
## $ e_fg_percent      <dbl> 0,486, 0,547, 0,557, 0,424, 0,566, 0,449, 0,450, 0,438, 0…
## $ ft                <dbl> 1,1, 1,4, 4,6, 0,6, 1,9, 1,2, 1,4, 0,7, 1,0, 2,9, 0,7, 0,…
## $ fta               <dbl> 1,8, 2,6, 6,1, 1,0, 2,2, 1,7, 1,9, 0,8, 1,1, 4,2, 1,0, 1,…
## $ ft_percent        <dbl> 0,595, 0,543, 0,753, 0,625, 0,873, 0,743, 0,722, 0,917, 0…
## $ orb               <dbl> 2,0, 4,6, 2,4, 1,0, 1,6, 0,6, 0,7, 0,1, 0,5, 3,4, 0,5, 0,…
## $ drb               <dbl> 4,5, 5,4, 7,6, 1,7, 3,9, 2,3, 2,6, 1,5, 2,9, 7,3, 1,4, 2,…
## $ trb               <dbl> 6,5, 10,0, 10,1, 2,7, 5,5, 2,9, 3,3, 1,5, 3,4, 10,8, 1,9,…
## $ ast               <dbl> 1,1, 3,4, 3,4, 0,7, 0,9, 2,4, 2,8, 1,1, 1,5, 1,6, 2,8, 2,…
## $ stl               <dbl> 0,5, 0,9, 1,4, 0,2, 0,3, 0,7, 0,8, 0,3, 0,7, 0,8, 1,3, 0,…
## $ blk               <dbl> 0,6, 0,8, 0,8, 0,3, 1,0, 0,4, 0,4, 0,3, 0,3, 1,3, 0,1, 0,…
## $ tov               <dbl> 1,2, 1,5, 2,6, 0,5, 0,9, 1,4, 1,7, 0,5, 0,7, 1,7, 0,7, 0,…
## $ pf                <dbl> 2,1, 2,0, 3,1, 1,1, 1,7, 1,6, 1,8, 1,0, 1,5, 1,7, 1,4, 1,…
## $ pts               <dbl> 9,1, 6,9, 19,1, 4,1, 12,9, 10,6, 12,8, 3,5, 11,1, 16,1, 6…
## $ player_additional <chr> "achiupr01", "adamsst01", "adebaba01", "aldamsa01", "aldr…

Advanced

Read the file:

df_advanced <- read_csv(
  './data/2022-12-27-per-player-advanced.csv'
) %>% 
  clean_names() %>% 
  remove_empty(quiet = FALSE) %>% 
  remove_constant(quiet = FALSE)
## value for "which" not specified, defaulting to c("rows", "cols")
## New names:
## Rows: 812 Columns: 30
## ── Column specification
## ───────────────────────────────────────────────────────────── Delimiter: "," chr
## (4): Player, Pos, Tm, Player-additional dbl (24): Rk, Age, G, MP, PER, TS%, 3PAr,
## FTr, ORB%, DRB%, TRB%, AST%, STL%, BLK%... lgl (2): ...20, ...25
## ℹ 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.
## No empty rows to remove.
## Removing 2 empty columns of 30 columns total (Removed: x20, x25).
## No constant columns to remove.
## • `` -> `...20`
## • `` -> `...25`

First look at the data:

df_advanced %>% glimpse()
## Rows: 812
## Columns: 28
## $ rk                <dbl> 1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 9, 10, 10, 10, 11, 12, 13, …
## $ player            <chr> "Precious Achiuwa", "Steven Adams", "Bam Adebayo", "Santi…
## $ pos               <chr> "C", "C", "C", "PF", "C", "SG", "SG", "SG", "SG", "C", "P…
## $ age               <dbl> 22, 28, 24, 21, 36, 23, 23, 23, 26, 23, 23, 28, 28, 28, 2…
## $ tm                <chr> "TOR", "MEM", "MIA", "MEM", "BRK", "TOT", "NOP", "UTA", "…
## $ g                 <dbl> 73, 76, 56, 32, 47, 65, 50, 15, 66, 56, 54, 16, 3, 13, 69…
## $ mp                <dbl> 1725, 1999, 1825, 360, 1050, 1466, 1317, 149, 1805, 1809,…
## $ per               <dbl> 12,7, 17,6, 21,8, 10,2, 19,6, 10,5, 10,5, 10,2, 12,7, 23,…
## $ ts_percent        <dbl> 0,503, 0,560, 0,608, 0,452, 0,604, 0,475, 0,474, 0,497, 0…
## $ x3p_ar            <dbl> 0,259, 0,003, 0,008, 0,364, 0,100, 0,497, 0,483, 0,688, 0…
## $ f_tr              <dbl> 0,217, 0,518, 0,466, 0,242, 0,223, 0,160, 0,153, 0,250, 0…
## $ orb_percent       <dbl> 8,7, 17,9, 8,7, 9,4, 7,8, 2,7, 3,0, 0,8, 1,9, 12,0, 3,2, …
## $ drb_percent       <dbl> 21,7, 22,0, 26,1, 16,1, 18,7, 11,5, 11,0, 15,6, 10,9, 24,…
## $ trb_percent       <dbl> 14,9, 19,9, 17,5, 12,6, 13,4, 7,1, 6,9, 8,5, 6,5, 18,4, 6…
## $ ast_percent       <dbl> 6,9, 16,1, 17,5, 7,7, 6,3, 16,1, 16,1, 15,5, 7,6, 8,2, 26…
## $ stl_percent       <dbl> 1,1, 1,6, 2,2, 0,8, 0,6, 1,5, 1,5, 1,7, 1,2, 1,2, 4,2, 1,…
## $ blk_percent       <dbl> 2,3, 2,7, 2,6, 2,5, 4,0, 1,5, 1,4, 2,4, 1,0, 3,7, 0,8, 1,…
## $ tov_percent       <dbl> 11,3, 19,6, 14,4, 9,9, 8,0, 11,3, 11,2, 13,1, 6,7, 12,7, …
## $ usg_percent       <dbl> 18,5, 12,0, 25,0, 18,4, 22,4, 24,1, 24,8, 17,9, 15,2, 18,…
## $ ows               <dbl> 0,4, 3,8, 3,6, -0,1, 2,1, -1,1, -1,1, 0,0, 2,8, 5,4, 1,0,…
## $ dws               <dbl> 2,1, 3,0, 3,5, 0,4, 1,0, 1,1, 0,9, 0,2, 1,4, 3,0, 1,1, 0,…
## $ ws                <dbl> 2,5, 6,8, 7,2, 0,3, 3,1, 0,1, -0,1, 0,2, 4,2, 8,5, 2,1, 0…
## $ ws_48             <dbl> 0,070, 0,163, 0,188, 0,044, 0,141, 0,003, -0,005, 0,070, …
## $ obpm              <dbl> -2,0, 1,0, 1,7, -4,2, 1,3, -1,8, -1,7, -2,9, 0,6, 2,7, -0…
## $ dbpm              <dbl> -0,6, 1,0, 2,1, -1,5, -0,6, -1,1, -1,3, 1,2, -0,2, 1,2, 2…
## $ bpm               <dbl> -2,6, 2,0, 3,8, -5,7, 0,7, -2,9, -3,0, -1,7, 0,4, 3,9, 1,…
## $ vorp              <dbl> -0,2, 2,0, 2,7, -0,3, 0,7, -0,3, -0,3, 0,0, 1,1, 2,7, 0,8…
## $ player_additional <chr> "achiupr01", "adamsst01", "adebaba01", "aldamsa01", "aldr…

Data dictionary

Per game

  • Rk: Rank.

  • Player: Player name.

  • Pos: Position.

  • Age: Player’s age on February 1 of the season.

  • Tm: Team.

  • G: Games.

  • GS: Games Started.

  • MP: Minutes Played Per Game.

  • FG: Field Goals Per Game.

  • FGA: Field Goal Attempts Per Game.

  • FG%: Field Goal Percentage.

  • 3P: 3-Point Field Goals Per Game.

  • 3PA: 3-Point Field Goal Attempts Per Game.

  • 3P%: 3-Point Field Goal Percentage.

  • 2P: 2-Point Field Goals Per Game.

  • 2PA: 2-Point Field Goal Attempts Per Game.

  • 2P%: 2-Point Field Goal Percentage.

  • eFG%: Effective Field Goal Percentage. Adjusts for a 3-point field goal being worth one more point than a 2-point field goal.

  • FT: Free Throws Per Game.

  • FTA: Free Throw Attempts Per Game.

  • FT%: Free Throw Percentage.

  • ORB: Offensive Rebounds Per Game.

  • DRB: Defensive Rebounds Per Game.

  • TRB: Total Rebounds Per Game.

  • AST: Assists Per Game.

  • STL: Steals Per Game.

  • BLK: Blocks Per Game.

  • TOV: Turnovers Per Game.

  • PF: Personal Fouls Per Game.

  • PTS: Points Per Game.

  • Player-additional: Unique identifier.

Advanced

  • Rk: Rank.

  • Player: Player name.

  • Pos: Position.

  • Age: Player’s age on February 1 of the season.

  • Tm: Team.

  • G: Games.

  • MP: Minutes Played.

  • PER: Player Efficiency Rating. A measure of per-minute production standardized such that the league average is 15.

  • TS%: True Shooting Percentage. A measure of shooting efficiency that takes into account 2-point field goals, 3-point field goals, and free throws.

  • 3PAr: 3-Point Attempt Rate. Percentage of FG Attempts from 3-Point Range.

  • FTr: Free Throw Attempt Rate. Number of FT Attempts Per FG Attempt.

  • ORB%: Offensive Rebound Percentage. An estimate of the percentage of available offensive rebounds a player grabbed while they were on the floor.

  • DRB%: Defensive Rebound Percentage. An estimate of the percentage of available defensive rebounds a player grabbed while they were on the floor.

  • TRB%: Total Rebound Percentage. An estimate of the percentage of available rebounds a player grabbed while they were on the floor.

  • AST%: Assist Percentage. An estimate of the percentage of teammate field goals a player assisted while they were on the floor.

  • STL%: Steal Percentage. An estimate of the percentage of opponent possessions that end with a steal by the player while they were on the floor.

  • BLK%: Block Percentage. An estimate of the percentage of opponent two-point field goal attempts blocked by the player while they were on the floor.

  • TOV%: Turnover Percentage. An estimate of turnovers committed per 100 plays.

  • USG%: Usage Percentage. An estimate of the percentage of team plays used by a player while they were on the floor.

  • OWS: Offensive Win Shares. An estimate of the number of wins contributed by a player due to offense.

  • DWS: Defensive Win Shares. An estimate of the number of wins contributed by a player due to defense.

  • WS: Win Shares. An estimate of the number of wins contributed by a player.

  • WS/48: Win Shares Per 48 Minutes. An estimate of the number of wins contributed by a player per 48 minutes (league average is approximately .100).

  • OBPM: Offensive Box Plus/Minus. A box score estimate of the offensive points per 100 possessions a player contributed above a league-average player, translated to an average team.

  • DBPM: Defensive Box Plus/Minus. A box score estimate of the defensive points per 100 possessions a player contributed above a league-average player, translated to an average team.

  • BPM: Box Plus/Minus. A box score estimate of the points per 100 possessions a player contributed above a league-average player, translated to an average team.

  • VORP: Value over Replacement Player. A box score estimate of the points per 100 TEAM possessions that a player contributed above a replacement-level (-2.0) player, translated to an average team and prorated to an 82-game season. Multiply by 2.70 to convert to wins over replacement.

  • Player-additional: Unique identifier.

Cleaning the data

Per game

  • Delete rk column:

    df_per_game <- 
      df_per_game %>% 
        select(-rk)
  • Rename all columns:

    original_names <- names(df_per_game)
    new_names <- c(
      'player',
      'position',
      'age',
      'team',
      'games',
      'games_started',
      'minutes_played_average',
      'goals_scored',
      'goal_attempts',
      'goal_pct',
      'goals_scored_3p',
      'goal_attempts_3p',
      'goal_pct_3p',
      'goals_scored_2p',
      'goal_attempts_2p',
      'goal_pct_2p',
      'goals_effective_pct',
      'free_throws_scored',
      'free_throw_attempts',
      'free_throw_pct',
      'rebounds_offense',
      'rebounds_defense',
      'rebounds_total',
      'assists',
      'steals',
      'blocks',
      'turnovers',
      'fouls',
      'points_scored',
      'player_id'
    )
    
    names(new_names) <- original_names
    
    paste(
      names(new_names), 
      new_names, 
      sep = ' -> ', 
      collapse = '\n'
    ) %>% 
      cat()
    ## player -> player
    ## pos -> position
    ## age -> age
    ## tm -> team
    ## g -> games
    ## gs -> games_started
    ## mp -> minutes_played_average
    ## fg -> goals_scored
    ## fga -> goal_attempts
    ## fg_percent -> goal_pct
    ## x3p -> goals_scored_3p
    ## x3pa -> goal_attempts_3p
    ## x3p_percent -> goal_pct_3p
    ## x2p -> goals_scored_2p
    ## x2pa -> goal_attempts_2p
    ## x2p_percent -> goal_pct_2p
    ## e_fg_percent -> goals_effective_pct
    ## ft -> free_throws_scored
    ## fta -> free_throw_attempts
    ## ft_percent -> free_throw_pct
    ## orb -> rebounds_offense
    ## drb -> rebounds_defense
    ## trb -> rebounds_total
    ## ast -> assists
    ## stl -> steals
    ## blk -> blocks
    ## tov -> turnovers
    ## pf -> fouls
    ## pts -> points_scored
    ## player_additional -> player_id
    df_per_game <- df_per_game %>% 
      rename_with(
        function(x) { new_names[x] }
      )
  • Find players that appear more than once and keep only the row that has the totals:

    dupes <- df_per_game %>% 
      get_dupes(player_id)
    dupes %>% 
      select(player, team, dupe_count) %>% 
      arrange(desc(dupe_count))

    For these players, we keep only the row for the totals (TOT):

    df_per_game <- df_per_game %>% 
      keep_only_totals(dupes)

Per game: summary

df_per_game %>% 
  dfSummary(silent = TRUE) %>% 
  print(method = 'render')
Variable Stats / Values Freqs (% of Valid) Graph Missing
player [character]
1. Aaron Gordon
2. Aaron Henry
3. Aaron Holiday
4. Aaron Nesmith
5. Aaron Wiggins
6. Abdel Nader
7. Ade Murkey
8. Admiral Schofield
9. Ahmad Caver
10. Al Horford
[ 595 others ]
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
595 ( 98,3% )
0 (0,0%)
position [character]
1. SG
2. SF
3. PG
4. C
5. PF
6. SF-SG
7. SG-PG
8. SG-SF
9. PG-SG
10. C-PF
[ 3 others ]
153 ( 25,3% )
116 ( 19,2% )
107 ( 17,7% )
106 ( 17,5% )
106 ( 17,5% )
4 ( 0,7% )
4 ( 0,7% )
3 ( 0,5% )
2 ( 0,3% )
1 ( 0,2% )
3 ( 0,5% )
0 (0,0%)
age [numeric]
Mean (sd) : 25,7 (4,1)
min ≤ med ≤ max:
19 ≤ 25 ≤ 41
IQR (CV) : 5 (0,2)
22 distinct values 0 (0,0%)
team [character]
1. TOT
2. OKC
3. DET
4. MEM
5. NYK
6. ATL
7. CLE
8. ORL
9. PHO
10. CHI
[ 21 others ]
97 ( 16,0% )
25 ( 4,1% )
22 ( 3,6% )
22 ( 3,6% )
20 ( 3,3% )
19 ( 3,1% )
19 ( 3,1% )
19 ( 3,1% )
19 ( 3,1% )
18 ( 3,0% )
325 ( 53,7% )
0 (0,0%)
games [numeric]
Mean (sd) : 43 (25,8)
min ≤ med ≤ max:
1 ≤ 48 ≤ 82
IQR (CV) : 49 (0,6)
82 distinct values 0 (0,0%)
games_started [numeric]
Mean (sd) : 20,3 (25,8)
min ≤ med ≤ max:
0 ≤ 7 ≤ 82
IQR (CV) : 35 (1,3)
78 distinct values 0 (0,0%)
minutes_played_average [numeric]
Mean (sd) : 18,9 (9,7)
min ≤ med ≤ max:
1 ≤ 18,1 ≤ 43,5
IQR (CV) : 16,2 (0,5)
280 distinct values 0 (0,0%)
goals_scored [numeric]
Mean (sd) : 3 (2,3)
min ≤ med ≤ max:
0 ≤ 2,6 ≤ 11,4
IQR (CV) : 2,8 (0,8)
95 distinct values 0 (0,0%)
goal_attempts [numeric]
Mean (sd) : 6,7 (4,8)
min ≤ med ≤ max:
0 ≤ 5,5 ≤ 21,8
IQR (CV) : 5,9 (0,7)
170 distinct values 0 (0,0%)
goal_pct [numeric]
Mean (sd) : 0,4 (0,1)
min ≤ med ≤ max:
0 ≤ 0,4 ≤ 1
IQR (CV) : 0,1 (0,3)
259 distinct values 9 (1,5%)
goals_scored_3p [numeric]
Mean (sd) : 0,9 (0,9)
min ≤ med ≤ max:
0 ≤ 0,7 ≤ 4,5
IQR (CV) : 1,2 (0,9)
38 distinct values 0 (0,0%)
goal_attempts_3p [numeric]
Mean (sd) : 2,7 (2,3)
min ≤ med ≤ max:
0 ≤ 2,1 ≤ 11,7
IQR (CV) : 3,2 (0,8)
91 distinct values 0 (0,0%)
goal_pct_3p [numeric]
Mean (sd) : 0,3 (0,1)
min ≤ med ≤ max:
0 ≤ 0,3 ≤ 1
IQR (CV) : 0,1 (0,4)
192 distinct values 44 (7,3%)
goals_scored_2p [numeric]
Mean (sd) : 2,1 (1,8)
min ≤ med ≤ max:
0 ≤ 1,7 ≤ 9,5
IQR (CV) : 2,1 (0,9)
74 distinct values 0 (0,0%)
goal_attempts_2p [numeric]
Mean (sd) : 4 (3,3)
min ≤ med ≤ max:
0 ≤ 3,2 ≤ 18,3
IQR (CV) : 3,9 (0,8)
132 distinct values 0 (0,0%)
goal_pct_2p [numeric]
Mean (sd) : 0,5 (0,2)
min ≤ med ≤ max:
0 ≤ 0,5 ≤ 1
IQR (CV) : 0,1 (0,3)
260 distinct values 16 (2,6%)
goals_effective_pct [numeric]
Mean (sd) : 0,5 (0,1)
min ≤ med ≤ max:
0 ≤ 0,5 ≤ 1
IQR (CV) : 0,1 (0,3)
248 distinct values 9 (1,5%)
free_throws_scored [numeric]
Mean (sd) : 1,3 (1,3)
min ≤ med ≤ max:
0 ≤ 0,9 ≤ 9,6
IQR (CV) : 1,2 (1)
59 distinct values 0 (0,0%)
free_throw_attempts [numeric]
Mean (sd) : 1,6 (1,6)
min ≤ med ≤ max:
0 ≤ 1,2 ≤ 11,8
IQR (CV) : 1,6 (1)
69 distinct values 0 (0,0%)
free_throw_pct [numeric]
Mean (sd) : 0,7 (0,1)
min ≤ med ≤ max:
0 ≤ 0,8 ≤ 1
IQR (CV) : 0,2 (0,2)
247 distinct values 59 (9,8%)
rebounds_offense [numeric]
Mean (sd) : 0,8 (0,7)
min ≤ med ≤ max:
0 ≤ 0,6 ≤ 4,6
IQR (CV) : 0,8 (0,9)
39 distinct values 0 (0,0%)
rebounds_defense [numeric]
Mean (sd) : 2,6 (1,8)
min ≤ med ≤ max:
0 ≤ 2,4 ≤ 11
IQR (CV) : 2,2 (0,7)
80 distinct values 0 (0,0%)
rebounds_total [numeric]
Mean (sd) : 3,4 (2,4)
min ≤ med ≤ max:
0 ≤ 3 ≤ 14,7
IQR (CV) : 2,7 (0,7)
106 distinct values 0 (0,0%)
assists [numeric]
Mean (sd) : 1,9 (1,8)
min ≤ med ≤ max:
0 ≤ 1,2 ≤ 10,8
IQR (CV) : 1,9 (1)
77 distinct values 0 (0,0%)
steals [numeric]
Mean (sd) : 0,6 (0,4)
min ≤ med ≤ max:
0 ≤ 0,5 ≤ 2,3
IQR (CV) : 0,6 (0,7)
23 distinct values 0 (0,0%)
blocks [numeric]
Mean (sd) : 0,4 (0,4)
min ≤ med ≤ max:
0 ≤ 0,3 ≤ 2,8
IQR (CV) : 0,4 (1)
23 distinct values 0 (0,0%)
turnovers [numeric]
Mean (sd) : 1 (0,8)
min ≤ med ≤ max:
0 ≤ 0,8 ≤ 4,5
IQR (CV) : 0,8 (0,8)
43 distinct values 0 (0,0%)
fouls [numeric]
Mean (sd) : 1,6 (0,8)
min ≤ med ≤ max:
0 ≤ 1,6 ≤ 3,8
IQR (CV) : 1,2 (0,5)
39 distinct values 0 (0,0%)
points_scored [numeric]
Mean (sd) : 8,2 (6,3)
min ≤ med ≤ max:
0 ≤ 6,9 ≤ 30,6
IQR (CV) : 7,6 (0,8)
202 distinct values 0 (0,0%)
player_id [character]
1. achiupr01
2. adamsst01
3. adebaba01
4. aldamsa01
5. aldrila01
6. alexani01
7. allengr01
8. allenja01
9. alvarjo01
10. anderju01
[ 595 others ]
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
595 ( 98,3% )
0 (0,0%)

Generated by summarytools 1.0.1 (R version 4.2.2)
2022-12-30

Per game: notes

  • Approximately \(16\%\) of players played for two or more teams during the season.

  • On average, a player plays only \(19\) minutes per game.

  • Columns that should contain percentages actually contain proportions.

  • All columns that contain proportions have some missing values. Fortunately, all of them will be discarded before we build the model, as they are derived — therefore, perfectly correlated with other columns.

  • What are the “other” positions?

    df_per_game %>% 
      count(position, sort = TRUE) %>% 
      slice_tail(n = 3)

Per game: more cleaning

  • Turn proportions into percentages:

    df_per_game <- df_per_game %>% 
      mutate(
        across(contains('_pct'), ~ .x * 100)
      )
  • Why are some percentages NA?

    df_per_game %>% 
      filter(is.na(goal_pct)) %>% 
      select(starts_with('goal'))

    Because they are \(0\%\) of \(0\).

    I will replace the NAs with zeroes:

    df_per_game <- df_per_game %>% 
      mutate(
        across(
          contains('_pct'),
          ~ if_else(
            is.na(.x), 0, .x
          )
        )
      )

Per game: another summary

df_per_game %>% 
  dfSummary(silent = TRUE) %>% 
  print(method = 'render')
Variable Stats / Values Freqs (% of Valid) Graph Missing
player [character]
1. Aaron Gordon
2. Aaron Henry
3. Aaron Holiday
4. Aaron Nesmith
5. Aaron Wiggins
6. Abdel Nader
7. Ade Murkey
8. Admiral Schofield
9. Ahmad Caver
10. Al Horford
[ 595 others ]
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
595 ( 98,3% )
0 (0,0%)
position [character]
1. SG
2. SF
3. PG
4. C
5. PF
6. SF-SG
7. SG-PG
8. SG-SF
9. PG-SG
10. C-PF
[ 3 others ]
153 ( 25,3% )
116 ( 19,2% )
107 ( 17,7% )
106 ( 17,5% )
106 ( 17,5% )
4 ( 0,7% )
4 ( 0,7% )
3 ( 0,5% )
2 ( 0,3% )
1 ( 0,2% )
3 ( 0,5% )
0 (0,0%)
age [numeric]
Mean (sd) : 25,7 (4,1)
min ≤ med ≤ max:
19 ≤ 25 ≤ 41
IQR (CV) : 5 (0,2)
22 distinct values 0 (0,0%)
team [character]
1. TOT
2. OKC
3. DET
4. MEM
5. NYK
6. ATL
7. CLE
8. ORL
9. PHO
10. CHI
[ 21 others ]
97 ( 16,0% )
25 ( 4,1% )
22 ( 3,6% )
22 ( 3,6% )
20 ( 3,3% )
19 ( 3,1% )
19 ( 3,1% )
19 ( 3,1% )
19 ( 3,1% )
18 ( 3,0% )
325 ( 53,7% )
0 (0,0%)
games [numeric]
Mean (sd) : 43 (25,8)
min ≤ med ≤ max:
1 ≤ 48 ≤ 82
IQR (CV) : 49 (0,6)
82 distinct values 0 (0,0%)
games_started [numeric]
Mean (sd) : 20,3 (25,8)
min ≤ med ≤ max:
0 ≤ 7 ≤ 82
IQR (CV) : 35 (1,3)
78 distinct values 0 (0,0%)
minutes_played_average [numeric]
Mean (sd) : 18,9 (9,7)
min ≤ med ≤ max:
1 ≤ 18,1 ≤ 43,5
IQR (CV) : 16,2 (0,5)
280 distinct values 0 (0,0%)
goals_scored [numeric]
Mean (sd) : 3 (2,3)
min ≤ med ≤ max:
0 ≤ 2,6 ≤ 11,4
IQR (CV) : 2,8 (0,8)
95 distinct values 0 (0,0%)
goal_attempts [numeric]
Mean (sd) : 6,7 (4,8)
min ≤ med ≤ max:
0 ≤ 5,5 ≤ 21,8
IQR (CV) : 5,9 (0,7)
170 distinct values 0 (0,0%)
goal_pct [numeric]
Mean (sd) : 43,2 (14,2)
min ≤ med ≤ max:
0 ≤ 44,1 ≤ 100
IQR (CV) : 10,3 (0,3)
259 distinct values 0 (0,0%)
goals_scored_3p [numeric]
Mean (sd) : 0,9 (0,9)
min ≤ med ≤ max:
0 ≤ 0,7 ≤ 4,5
IQR (CV) : 1,2 (0,9)
38 distinct values 0 (0,0%)
goal_attempts_3p [numeric]
Mean (sd) : 2,7 (2,3)
min ≤ med ≤ max:
0 ≤ 2,1 ≤ 11,7
IQR (CV) : 3,2 (0,8)
91 distinct values 0 (0,0%)
goal_pct_3p [numeric]
Mean (sd) : 28,3 (14,3)
min ≤ med ≤ max:
0 ≤ 32,7 ≤ 100
IQR (CV) : 13,2 (0,5)
192 distinct values 0 (0,0%)
goals_scored_2p [numeric]
Mean (sd) : 2,1 (1,8)
min ≤ med ≤ max:
0 ≤ 1,7 ≤ 9,5
IQR (CV) : 2,1 (0,9)
74 distinct values 0 (0,0%)
goal_attempts_2p [numeric]
Mean (sd) : 4 (3,3)
min ≤ med ≤ max:
0 ≤ 3,2 ≤ 18,3
IQR (CV) : 3,9 (0,8)
132 distinct values 0 (0,0%)
goal_pct_2p [numeric]
Mean (sd) : 49,7 (17,1)
min ≤ med ≤ max:
0 ≤ 51,9 ≤ 100
IQR (CV) : 12,4 (0,3)
260 distinct values 0 (0,0%)
goals_effective_pct [numeric]
Mean (sd) : 49,4 (14,7)
min ≤ med ≤ max:
0 ≤ 52 ≤ 100
IQR (CV) : 9,5 (0,3)
248 distinct values 0 (0,0%)
free_throws_scored [numeric]
Mean (sd) : 1,3 (1,3)
min ≤ med ≤ max:
0 ≤ 0,9 ≤ 9,6
IQR (CV) : 1,2 (1)
59 distinct values 0 (0,0%)
free_throw_attempts [numeric]
Mean (sd) : 1,6 (1,6)
min ≤ med ≤ max:
0 ≤ 1,2 ≤ 11,8
IQR (CV) : 1,6 (1)
69 distinct values 0 (0,0%)
free_throw_pct [numeric]
Mean (sd) : 67,5 (26,3)
min ≤ med ≤ max:
0 ≤ 75,3 ≤ 100
IQR (CV) : 21,1 (0,4)
247 distinct values 0 (0,0%)
rebounds_offense [numeric]
Mean (sd) : 0,8 (0,7)
min ≤ med ≤ max:
0 ≤ 0,6 ≤ 4,6
IQR (CV) : 0,8 (0,9)
39 distinct values 0 (0,0%)
rebounds_defense [numeric]
Mean (sd) : 2,6 (1,8)
min ≤ med ≤ max:
0 ≤ 2,4 ≤ 11
IQR (CV) : 2,2 (0,7)
80 distinct values 0 (0,0%)
rebounds_total [numeric]
Mean (sd) : 3,4 (2,4)
min ≤ med ≤ max:
0 ≤ 3 ≤ 14,7
IQR (CV) : 2,7 (0,7)
106 distinct values 0 (0,0%)
assists [numeric]
Mean (sd) : 1,9 (1,8)
min ≤ med ≤ max:
0 ≤ 1,2 ≤ 10,8
IQR (CV) : 1,9 (1)
77 distinct values 0 (0,0%)
steals [numeric]
Mean (sd) : 0,6 (0,4)
min ≤ med ≤ max:
0 ≤ 0,5 ≤ 2,3
IQR (CV) : 0,6 (0,7)
23 distinct values 0 (0,0%)
blocks [numeric]
Mean (sd) : 0,4 (0,4)
min ≤ med ≤ max:
0 ≤ 0,3 ≤ 2,8
IQR (CV) : 0,4 (1)
23 distinct values 0 (0,0%)
turnovers [numeric]
Mean (sd) : 1 (0,8)
min ≤ med ≤ max:
0 ≤ 0,8 ≤ 4,5
IQR (CV) : 0,8 (0,8)
43 distinct values 0 (0,0%)
fouls [numeric]
Mean (sd) : 1,6 (0,8)
min ≤ med ≤ max:
0 ≤ 1,6 ≤ 3,8
IQR (CV) : 1,2 (0,5)
39 distinct values 0 (0,0%)
points_scored [numeric]
Mean (sd) : 8,2 (6,3)
min ≤ med ≤ max:
0 ≤ 6,9 ≤ 30,6
IQR (CV) : 7,6 (0,8)
202 distinct values 0 (0,0%)
player_id [character]
1. achiupr01
2. adamsst01
3. adebaba01
4. aldamsa01
5. aldrila01
6. alexani01
7. allengr01
8. allenja01
9. alvarjo01
10. anderju01
[ 595 others ]
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
595 ( 98,3% )
0 (0,0%)

Generated by summarytools 1.0.1 (R version 4.2.2)
2022-12-30

Advanced

  • Delete rk column:

    df_advanced <- 
      df_advanced %>% 
        select(-rk)
  • Rename all columns:

    original_names <- names(df_advanced)
    new_names <- c(
      'player',
      'position',
      'age',
      'team',
      'games',
      'minutes_played_total',
      'efficiency',
      'true_shooting_pct',
      'attempt_rate_3p',
      'attempt_rate_free_throw',
      'rebound_offense_pct',
      'rebound_defense_pct',
      'rebound_total_pct',
      'assist_pct',
      'steal_pct',
      'block_pct',
      'turnover_pct',
      'usage_pct',
      'win_shares_offense',
      'win_shares_defense',
      'win_shares',
      'win_shares_48',
      'plus_minus_offense',
      'plus_minus_defense',
      'plus_minus',
      'value_over_replacement',
      'player_id'
    )
    
    names(new_names) <- original_names
    
    paste(
      names(new_names), 
      new_names, 
      sep = ' -> ', 
      collapse = '\n'
    ) %>% 
      cat()
    ## player -> player
    ## pos -> position
    ## age -> age
    ## tm -> team
    ## g -> games
    ## mp -> minutes_played_total
    ## per -> efficiency
    ## ts_percent -> true_shooting_pct
    ## x3p_ar -> attempt_rate_3p
    ## f_tr -> attempt_rate_free_throw
    ## orb_percent -> rebound_offense_pct
    ## drb_percent -> rebound_defense_pct
    ## trb_percent -> rebound_total_pct
    ## ast_percent -> assist_pct
    ## stl_percent -> steal_pct
    ## blk_percent -> block_pct
    ## tov_percent -> turnover_pct
    ## usg_percent -> usage_pct
    ## ows -> win_shares_offense
    ## dws -> win_shares_defense
    ## ws -> win_shares
    ## ws_48 -> win_shares_48
    ## obpm -> plus_minus_offense
    ## dbpm -> plus_minus_defense
    ## bpm -> plus_minus
    ## vorp -> value_over_replacement
    ## player_additional -> player_id
    df_advanced <- df_advanced %>% 
      rename_with(
        function(x) { new_names[x] }
      )
  • Find players that appear more than once and keep only the row that has the totals:

    dupes <- df_advanced %>% 
      get_dupes(player_id)
    dupes %>% 
      select(player, team, dupe_count) %>% 
      arrange(desc(dupe_count))

    For these players, we keep only the row for the totals (TOT):

    df_advanced <- df_advanced %>% 
      keep_only_totals(dupes)

Advanced: summary

df_advanced %>% 
  dfSummary(silent = TRUE) %>% 
  print(method = 'render')
Variable Stats / Values Freqs (% of Valid) Graph Missing
player [character]
1. Aaron Gordon
2. Aaron Henry
3. Aaron Holiday
4. Aaron Nesmith
5. Aaron Wiggins
6. Abdel Nader
7. Ade Murkey
8. Admiral Schofield
9. Ahmad Caver
10. Al Horford
[ 595 others ]
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
595 ( 98,3% )
0 (0,0%)
position [character]
1. SG
2. SF
3. PG
4. C
5. PF
6. SF-SG
7. SG-PG
8. SG-SF
9. PG-SG
10. C-PF
[ 3 others ]
153 ( 25,3% )
116 ( 19,2% )
107 ( 17,7% )
106 ( 17,5% )
106 ( 17,5% )
4 ( 0,7% )
4 ( 0,7% )
3 ( 0,5% )
2 ( 0,3% )
1 ( 0,2% )
3 ( 0,5% )
0 (0,0%)
age [numeric]
Mean (sd) : 25,7 (4,1)
min ≤ med ≤ max:
19 ≤ 25 ≤ 41
IQR (CV) : 5 (0,2)
22 distinct values 0 (0,0%)
team [character]
1. TOT
2. OKC
3. DET
4. MEM
5. NYK
6. ATL
7. CLE
8. ORL
9. PHO
10. CHI
[ 21 others ]
97 ( 16,0% )
25 ( 4,1% )
22 ( 3,6% )
22 ( 3,6% )
20 ( 3,3% )
19 ( 3,1% )
19 ( 3,1% )
19 ( 3,1% )
19 ( 3,1% )
18 ( 3,0% )
325 ( 53,7% )
0 (0,0%)
games [numeric]
Mean (sd) : 43 (25,8)
min ≤ med ≤ max:
1 ≤ 48 ≤ 82
IQR (CV) : 49 (0,6)
82 distinct values 0 (0,0%)
minutes_played_total [numeric]
Mean (sd) : 981,4 (809,5)
min ≤ med ≤ max:
1 ≤ 883 ≤ 2854
IQR (CV) : 1474 (0,8)
501 distinct values 0 (0,0%)
efficiency [numeric]
Mean (sd) : 12,5 (7,8)
min ≤ med ≤ max:
-45,2 ≤ 12,7 ≤ 76,2
IQR (CV) : 6,4 (0,6)
228 distinct values 0 (0,0%)
true_shooting_pct [numeric]
Mean (sd) : 0,5 (0,1)
min ≤ med ≤ max:
0 ≤ 0,6 ≤ 1
IQR (CV) : 0,1 (0,3)
261 distinct values 8 (1,3%)
attempt_rate_3p [numeric]
Mean (sd) : 0,4 (0,2)
min ≤ med ≤ max:
0 ≤ 0,4 ≤ 1
IQR (CV) : 0,3 (0,6)
366 distinct values 9 (1,5%)
attempt_rate_free_throw [numeric]
Mean (sd) : 0,2 (0,2)
min ≤ med ≤ max:
0 ≤ 0,2 ≤ 2
IQR (CV) : 0,2 (0,8)
312 distinct values 9 (1,5%)
rebound_offense_pct [numeric]
Mean (sd) : 5,2 (5,2)
min ≤ med ≤ max:
0 ≤ 3,5 ≤ 56,6
IQR (CV) : 5,1 (1)
152 distinct values 0 (0,0%)
rebound_defense_pct [numeric]
Mean (sd) : 14,7 (6,8)
min ≤ med ≤ max:
0 ≤ 13,4 ≤ 40,6
IQR (CV) : 8 (0,5)
213 distinct values 0 (0,0%)
rebound_total_pct [numeric]
Mean (sd) : 9,9 (5,2)
min ≤ med ≤ max:
0 ≤ 8,7 ≤ 44,7
IQR (CV) : 6,3 (0,5)
177 distinct values 0 (0,0%)
assist_pct [numeric]
Mean (sd) : 13 (9,2)
min ≤ med ≤ max:
0 ≤ 10,5 ≤ 64,1
IQR (CV) : 10,1 (0,7)
239 distinct values 0 (0,0%)
steal_pct [numeric]
Mean (sd) : 1,7 (1,9)
min ≤ med ≤ max:
0 ≤ 1,4 ≤ 25
IQR (CV) : 0,9 (1,1)
55 distinct values 0 (0,0%)
block_pct [numeric]
Mean (sd) : 1,8 (2)
min ≤ med ≤ max:
0 ≤ 1,3 ≤ 30
IQR (CV) : 1,8 (1,1)
72 distinct values 0 (0,0%)
turnover_pct [numeric]
Mean (sd) : 12,2 (6,7)
min ≤ med ≤ max:
0 ≤ 11,6 ≤ 58,1
IQR (CV) : 5,6 (0,6)
176 distinct values 8 (1,3%)
usage_pct [numeric]
Mean (sd) : 18,2 (6,4)
min ≤ med ≤ max:
0 ≤ 17,5 ≤ 54,6
IQR (CV) : 7 (0,3)
213 distinct values 0 (0,0%)
win_shares_offense [numeric]
Mean (sd) : 1,1 (1,7)
min ≤ med ≤ max:
-3 ≤ 0,5 ≤ 10,8
IQR (CV) : 1,8 (1,6)
78 distinct values 0 (0,0%)
win_shares_defense [numeric]
Mean (sd) : 1 (1)
min ≤ med ≤ max:
-0,1 ≤ 0,7 ≤ 4,6
IQR (CV) : 1,3 (1)
45 distinct values 0 (0,0%)
win_shares [numeric]
Mean (sd) : 2,1 (2,5)
min ≤ med ≤ max:
-1,6 ≤ 1,2 ≤ 15,2
IQR (CV) : 3,1 (1,2)
98 distinct values 0 (0,0%)
win_shares_48 [numeric]
Mean (sd) : 0,1 (0,1)
min ≤ med ≤ max:
-1,2 ≤ 0,1 ≤ 1,2
IQR (CV) : 0,1 (1,9)
263 distinct values 0 (0,0%)
plus_minus_offense [numeric]
Mean (sd) : -1,8 (4,5)
min ≤ med ≤ max:
-33,9 ≤ -1,4 ≤ 31
IQR (CV) : 3,6 (-2,5)
160 distinct values 0 (0,0%)
plus_minus_defense [numeric]
Mean (sd) : -0,2 (2,2)
min ≤ med ≤ max:
-14,5 ≤ -0,2 ≤ 11,8
IQR (CV) : 1,9 (-8,9)
97 distinct values 0 (0,0%)
plus_minus [numeric]
Mean (sd) : -2,1 (5,7)
min ≤ med ≤ max:
-42,6 ≤ -1,5 ≤ 36,9
IQR (CV) : 4,4 (-2,7)
180 distinct values 0 (0,0%)
value_over_replacement [numeric]
Mean (sd) : 0,5 (1,1)
min ≤ med ≤ max:
-1,2 ≤ 0 ≤ 9,8
IQR (CV) : 0,9 (2,3)
57 distinct values 0 (0,0%)
player_id [character]
1. achiupr01
2. adamsst01
3. adebaba01
4. aldamsa01
5. aldrila01
6. alexani01
7. allengr01
8. allenja01
9. alvarjo01
10. anderju01
[ 595 others ]
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
595 ( 98,3% )
0 (0,0%)

Generated by summarytools 1.0.1 (R version 4.2.2)
2022-12-30

Advanced: notes

  • Here, percentages are really percentages (between \(0\) and \(100\)), except for true_shooting_pct.

  • Offensive rebounds are harder than defensive rebounds.

  • Most statistics here have right-skewed distributions.

  • What are the “other” positions?

    df_advanced %>% 
      count(position, sort = TRUE) %>% 
      slice_tail(n = 3)
  • Are the players in the advanced data frame the same as in the per game data frame?

    identical(
      sort(df_per_game$player_id),
      sort(df_advanced$player_id)
    )
    ## [1] TRUE

Advanced: more cleaning

  • Fix true_shooting_pct:

    df_advanced <- df_advanced %>% 
      mutate(true_shooting_pct = 100 * true_shooting_pct)
  • Replace the NAs with zeroes:

    df_advanced <- df_advanced %>% 
      mutate(
        across(
          .fns = 
            ~ if (is.numeric(.x)) {
                if_else(is.na(.x), 0, .x)
            } else { .x }
        )
      )

Advanced: another summary

df_advanced %>% 
  dfSummary(silent = TRUE) %>% 
  print(method = 'render')
Variable Stats / Values Freqs (% of Valid) Graph Missing
player [character]
1. Aaron Gordon
2. Aaron Henry
3. Aaron Holiday
4. Aaron Nesmith
5. Aaron Wiggins
6. Abdel Nader
7. Ade Murkey
8. Admiral Schofield
9. Ahmad Caver
10. Al Horford
[ 595 others ]
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
595 ( 98,3% )
0 (0,0%)
position [character]
1. SG
2. SF
3. PG
4. C
5. PF
6. SF-SG
7. SG-PG
8. SG-SF
9. PG-SG
10. C-PF
[ 3 others ]
153 ( 25,3% )
116 ( 19,2% )
107 ( 17,7% )
106 ( 17,5% )
106 ( 17,5% )
4 ( 0,7% )
4 ( 0,7% )
3 ( 0,5% )
2 ( 0,3% )
1 ( 0,2% )
3 ( 0,5% )
0 (0,0%)
age [numeric]
Mean (sd) : 25,7 (4,1)
min ≤ med ≤ max:
19 ≤ 25 ≤ 41
IQR (CV) : 5 (0,2)
22 distinct values 0 (0,0%)
team [character]
1. TOT
2. OKC
3. DET
4. MEM
5. NYK
6. ATL
7. CLE
8. ORL
9. PHO
10. CHI
[ 21 others ]
97 ( 16,0% )
25 ( 4,1% )
22 ( 3,6% )
22 ( 3,6% )
20 ( 3,3% )
19 ( 3,1% )
19 ( 3,1% )
19 ( 3,1% )
19 ( 3,1% )
18 ( 3,0% )
325 ( 53,7% )
0 (0,0%)
games [numeric]
Mean (sd) : 43 (25,8)
min ≤ med ≤ max:
1 ≤ 48 ≤ 82
IQR (CV) : 49 (0,6)
82 distinct values 0 (0,0%)
minutes_played_total [numeric]
Mean (sd) : 981,4 (809,5)
min ≤ med ≤ max:
1 ≤ 883 ≤ 2854
IQR (CV) : 1474 (0,8)
501 distinct values 0 (0,0%)
efficiency [numeric]
Mean (sd) : 12,5 (7,8)
min ≤ med ≤ max:
-45,2 ≤ 12,7 ≤ 76,2
IQR (CV) : 6,4 (0,6)
228 distinct values 0 (0,0%)
true_shooting_pct [numeric]
Mean (sd) : 52,4 (14,5)
min ≤ med ≤ max:
0 ≤ 54,9 ≤ 100
IQR (CV) : 9,3 (0,3)
261 distinct values 0 (0,0%)
attempt_rate_3p [numeric]
Mean (sd) : 0,4 (0,2)
min ≤ med ≤ max:
0 ≤ 0,4 ≤ 1
IQR (CV) : 0,3 (0,6)
366 distinct values 0 (0,0%)
attempt_rate_free_throw [numeric]
Mean (sd) : 0,2 (0,2)
min ≤ med ≤ max:
0 ≤ 0,2 ≤ 2
IQR (CV) : 0,2 (0,8)
312 distinct values 0 (0,0%)
rebound_offense_pct [numeric]
Mean (sd) : 5,2 (5,2)
min ≤ med ≤ max:
0 ≤ 3,5 ≤ 56,6
IQR (CV) : 5,1 (1)
152 distinct values 0 (0,0%)
rebound_defense_pct [numeric]
Mean (sd) : 14,7 (6,8)
min ≤ med ≤ max:
0 ≤ 13,4 ≤ 40,6
IQR (CV) : 8 (0,5)
213 distinct values 0 (0,0%)
rebound_total_pct [numeric]
Mean (sd) : 9,9 (5,2)
min ≤ med ≤ max:
0 ≤ 8,7 ≤ 44,7
IQR (CV) : 6,3 (0,5)
177 distinct values 0 (0,0%)
assist_pct [numeric]
Mean (sd) : 13 (9,2)
min ≤ med ≤ max:
0 ≤ 10,5 ≤ 64,1
IQR (CV) : 10,1 (0,7)
239 distinct values 0 (0,0%)
steal_pct [numeric]
Mean (sd) : 1,7 (1,9)
min ≤ med ≤ max:
0 ≤ 1,4 ≤ 25
IQR (CV) : 0,9 (1,1)
55 distinct values 0 (0,0%)
block_pct [numeric]
Mean (sd) : 1,8 (2)
min ≤ med ≤ max:
0 ≤ 1,3 ≤ 30
IQR (CV) : 1,8 (1,1)
72 distinct values 0 (0,0%)
turnover_pct [numeric]
Mean (sd) : 12 (6,8)
min ≤ med ≤ max:
0 ≤ 11,5 ≤ 58,1
IQR (CV) : 5,8 (0,6)
176 distinct values 0 (0,0%)
usage_pct [numeric]
Mean (sd) : 18,2 (6,4)
min ≤ med ≤ max:
0 ≤ 17,5 ≤ 54,6
IQR (CV) : 7 (0,3)
213 distinct values 0 (0,0%)
win_shares_offense [numeric]
Mean (sd) : 1,1 (1,7)
min ≤ med ≤ max:
-3 ≤ 0,5 ≤ 10,8
IQR (CV) : 1,8 (1,6)
78 distinct values 0 (0,0%)
win_shares_defense [numeric]
Mean (sd) : 1 (1)
min ≤ med ≤ max:
-0,1 ≤ 0,7 ≤ 4,6
IQR (CV) : 1,3 (1)
45 distinct values 0 (0,0%)
win_shares [numeric]
Mean (sd) : 2,1 (2,5)
min ≤ med ≤ max:
-1,6 ≤ 1,2 ≤ 15,2
IQR (CV) : 3,1 (1,2)
98 distinct values 0 (0,0%)
win_shares_48 [numeric]
Mean (sd) : 0,1 (0,1)
min ≤ med ≤ max:
-1,2 ≤ 0,1 ≤ 1,2
IQR (CV) : 0,1 (1,9)
263 distinct values 0 (0,0%)
plus_minus_offense [numeric]
Mean (sd) : -1,8 (4,5)
min ≤ med ≤ max:
-33,9 ≤ -1,4 ≤ 31
IQR (CV) : 3,6 (-2,5)
160 distinct values 0 (0,0%)
plus_minus_defense [numeric]
Mean (sd) : -0,2 (2,2)
min ≤ med ≤ max:
-14,5 ≤ -0,2 ≤ 11,8
IQR (CV) : 1,9 (-8,9)
97 distinct values 0 (0,0%)
plus_minus [numeric]
Mean (sd) : -2,1 (5,7)
min ≤ med ≤ max:
-42,6 ≤ -1,5 ≤ 36,9
IQR (CV) : 4,4 (-2,7)
180 distinct values 0 (0,0%)
value_over_replacement [numeric]
Mean (sd) : 0,5 (1,1)
min ≤ med ≤ max:
-1,2 ≤ 0 ≤ 9,8
IQR (CV) : 0,9 (2,3)
57 distinct values 0 (0,0%)
player_id [character]
1. achiupr01
2. adamsst01
3. adebaba01
4. aldamsa01
5. aldrila01
6. alexani01
7. allengr01
8. allenja01
9. alvarjo01
10. anderju01
[ 595 others ]
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
1 ( 0,2% )
595 ( 98,3% )
0 (0,0%)

Generated by summarytools 1.0.1 (R version 4.2.2)
2022-12-30

LS0tCnRpdGxlOiAnTGluZWFyIHJlZ3Jlc3Npb246IGRlZmVuc2UgfiAuJwpzdWJ0aXRsZTogJzIwMjEtLTIwMjInCmF1dGhvcjogJ2ZuYXVmZWwsIHJvbXVsb3IzJwplbWFpbDogJ2h0dHBzOi8vZm5hdWZlbC5naXRodWIuaW8vJwpkYXRlOiAnICAgKHYuIGByIGZvcm1hdChTeXMuRGF0ZSgpLCAiJWQvJW0vJVkiKWApJwpsYW5nOiAnZW4nCgpvdXRwdXQ6IAogICMgVG8gaW5zdGFsbCB0aGVzZSBvdXRwdXQgZm9ybWF0cywgcnVuCiAgIyAgIGluc3RhbGwucGFja2FnZXMoImRldnRvb2xzIikKICAjICAgZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJmbmF1ZmVsL2ZuYXVmZWxSbWQiKQogIGZuYXVmZWxSbWQ6Omh0bWxfcmVwb3J0OgogICAgbnVtYmVyX3NlY3Rpb25zOiBubwogICAgY29kZV9mb2xkaW5nOiAnaGlkZScKICBmbmF1ZmVsUm1kOjpwZGZfcmVwb3J0OgogICAgbnVtYmVyX3NlY3Rpb25zOiBubwoKIyBMYVRlWCAvIHBkZiBvcHRpb25zCiMKIyBGb3IgbW9yZSBvcHRpb25zLCBzZWUKIyBodHRwczovL3BhbmRvYy5vcmcvTUFOVUFMLmh0bWwjdmFyaWFibGVzLWZvci1sYXRleApkb2N1bWVudGNsYXNzOiBhcnRpY2xlCmNsYXNzb3B0aW9uOiAnMTFwdCcKZ2VvbWV0cnk6ICdtYXJnaW49MWluJwpiaWJsaW9ncmFwaHk6IFtdCmJpYmxpby1zdHlsZTogYXBhbGlrZQpsaW5rLWNpdGF0aW9uczogeWVzCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CiMgVGhlIG5leHQgY29tbWFuZCBjb25maWd1cmVzIE1BTlkgdGhpbmdzIGFuZCBsb2FkcyBxdWl0ZSBhIGZldyBwYWNrYWdlcy4KIyAKIyBJZiB5b3Ugd2FudCB0byBzZWUgd2hhdCdzIGJlaW5nIGRvbmUsIGV4ZWN1dGUgCiMgCiMgICBjYXQoCiMgICAgIHN5c3RlbS5maWxlKAojICAgICAgICJybWFya2Rvd24vcmVzb3VyY2VzL1IvX2NvbW1vbl9yZXBvcnQuUiIsIAojICAgICAgIHBhY2thZ2UgPSAiZm5hdWZlbFJtZCIKIyAgICAgKQojICAgKQojIAojIHRvIGZpbmQgb3V0IHRoZSBsb2NhdGlvbiBvZiB0aGUgZmlsZS4gVGhlbiBvcGVuIHRoZSBmaWxlLgojIAojIElmIHlvdSB3YW50IHRvIGNoYW5nZSB0aGUgY29uZmlndXJhdGlvbiwgY29weSB0aGUgZmlsZSwgZWRpdCBpdCwgYW5kCiMgc291cmNlIGl0IGluc3RlYWQgb2YgdGhlIHBhY2thZ2UgZmlsZS4gCiMgCiMgT3Igc2ltcGx5IHdyaXRlIHlvdXIgY29tbWFuZHMgaGVyZSBpbiB0aGlzIGNvZGUgY2h1bmsuCgpzb3VyY2UoCiAgc3lzdGVtLmZpbGUoCiAgICAicm1hcmtkb3duL3Jlc291cmNlcy9SL19jb21tb25fcmVwb3J0LlIiLAogICAgcGFja2FnZSA9ICJmbmF1ZmVsUm1kIgogICkKKQoKIyBTdW1tYXJ5dG9vbHMgb3B0aW9ucwpzdF9vcHRpb25zKAogIGxhbmcgPSAnZW4nLAopCgpsaWJyYXJ5KGphbml0b3IpCgpzb3VyY2UoJ1IvdXRpbHMuUicpCmBgYAoKCiMgSW50cm9kdWN0aW9uCgpUaGlzIHJlcG9ydCB1c2VzIGRhdGEgZG93bmxvYWRlZCBmcm9tID8/Py4KCgojIFJlYWQgdGhlIGRhdGEKCiMjIFBlciBnYW1lCgpSZWFkIHRoZSBmaWxlOgoKYGBge3IgY2FjaGU9VFJVRX0KZGZfcGVyX2dhbWUgPC0gcmVhZF9jc3YoCiAgJy4vZGF0YS8yMDIyLTEyLTI3LXBlci1wbGF5ZXItcGVyLWdhbWUuY3N2JwopICU+JSAKICBjbGVhbl9uYW1lcygpICU+JSAKICByZW1vdmVfZW1wdHkocXVpZXQgPSBGQUxTRSkgJT4lIAogIHJlbW92ZV9jb25zdGFudChxdWlldCA9IEZBTFNFKQpgYGAKCkZpcnN0IGxvb2sgYXQgdGhlIGRhdGE6CgpgYGB7cn0KZGZfcGVyX2dhbWUgJT4lIGdsaW1wc2UoKQpgYGAKCgojIyBBZHZhbmNlZAoKUmVhZCB0aGUgZmlsZToKCmBgYHtyIGNhY2hlPVRSVUV9CmRmX2FkdmFuY2VkIDwtIHJlYWRfY3N2KAogICcuL2RhdGEvMjAyMi0xMi0yNy1wZXItcGxheWVyLWFkdmFuY2VkLmNzdicKKSAlPiUgCiAgY2xlYW5fbmFtZXMoKSAlPiUgCiAgcmVtb3ZlX2VtcHR5KHF1aWV0ID0gRkFMU0UpICU+JSAKICByZW1vdmVfY29uc3RhbnQocXVpZXQgPSBGQUxTRSkKYGBgCgpGaXJzdCBsb29rIGF0IHRoZSBkYXRhOgoKYGBge3J9CmRmX2FkdmFuY2VkICU+JSBnbGltcHNlKCkKYGBgCgoKIyBEYXRhIGRpY3Rpb25hcnkKCiMjIFBlciBnYW1lCgotICoqUms6KiogUmFuay4KCi0gKipQbGF5ZXI6KiogUGxheWVyIG5hbWUuCgotICoqUG9zOioqIFBvc2l0aW9uLgoKLSAqKkFnZToqKiBQbGF5ZXIncyBhZ2Ugb24gRmVicnVhcnkgMSBvZiB0aGUgc2Vhc29uLgoKLSAqKlRtOioqIFRlYW0uCgotICoqRzoqKiBHYW1lcy4KCi0gKipHUzoqKiBHYW1lcyBTdGFydGVkLgoKLSAqKk1QOioqIE1pbnV0ZXMgUGxheWVkIFBlciBHYW1lLgoKLSAqKkZHOioqIEZpZWxkIEdvYWxzIFBlciBHYW1lLgoKLSAqKkZHQToqKiBGaWVsZCBHb2FsIEF0dGVtcHRzIFBlciBHYW1lLgoKLSAqKkZHJToqKiBGaWVsZCBHb2FsIFBlcmNlbnRhZ2UuCgotICoqM1A6KiogMy1Qb2ludCBGaWVsZCBHb2FscyBQZXIgR2FtZS4KCi0gKiozUEE6KiogMy1Qb2ludCBGaWVsZCBHb2FsIEF0dGVtcHRzIFBlciBHYW1lLgoKLSAqKjNQJToqKiAzLVBvaW50IEZpZWxkIEdvYWwgUGVyY2VudGFnZS4KCi0gKioyUDoqKiAyLVBvaW50IEZpZWxkIEdvYWxzIFBlciBHYW1lLgoKLSAqKjJQQToqKiAyLVBvaW50IEZpZWxkIEdvYWwgQXR0ZW1wdHMgUGVyIEdhbWUuCgotICoqMlAlOioqIDItUG9pbnQgRmllbGQgR29hbCBQZXJjZW50YWdlLgoKLSAqKmVGRyU6KiogRWZmZWN0aXZlIEZpZWxkIEdvYWwgUGVyY2VudGFnZS4gQWRqdXN0cyBmb3IgYSAzLXBvaW50IGZpZWxkIGdvYWwgYmVpbmcgd29ydGggb25lIG1vcmUgcG9pbnQgdGhhbiBhIDItcG9pbnQgZmllbGQgZ29hbC4KCi0gKipGVDoqKiBGcmVlIFRocm93cyBQZXIgR2FtZS4KCi0gKipGVEE6KiogRnJlZSBUaHJvdyBBdHRlbXB0cyBQZXIgR2FtZS4KCi0gKipGVCU6KiogRnJlZSBUaHJvdyBQZXJjZW50YWdlLgoKLSAqKk9SQjoqKiBPZmZlbnNpdmUgUmVib3VuZHMgUGVyIEdhbWUuCgotICoqRFJCOioqIERlZmVuc2l2ZSBSZWJvdW5kcyBQZXIgR2FtZS4KCi0gKipUUkI6KiogVG90YWwgUmVib3VuZHMgUGVyIEdhbWUuCgotICoqQVNUOioqIEFzc2lzdHMgUGVyIEdhbWUuCgotICoqU1RMOioqIFN0ZWFscyBQZXIgR2FtZS4KCi0gKipCTEs6KiogQmxvY2tzIFBlciBHYW1lLgoKLSAqKlRPVjoqKiBUdXJub3ZlcnMgUGVyIEdhbWUuCgotICoqUEY6KiogUGVyc29uYWwgRm91bHMgUGVyIEdhbWUuCgotICoqUFRTOioqIFBvaW50cyBQZXIgR2FtZS4KCi0gKipQbGF5ZXItYWRkaXRpb25hbDoqKiBVbmlxdWUgaWRlbnRpZmllci4KCgojIyBBZHZhbmNlZAoKLSAqKlJrOioqIFJhbmsuCgotICoqUGxheWVyOioqIFBsYXllciBuYW1lLgoKLSAqKlBvczoqKiBQb3NpdGlvbi4KCi0gKipBZ2U6KiogUGxheWVyJ3MgYWdlIG9uIEZlYnJ1YXJ5IDEgb2YgdGhlIHNlYXNvbi4KCi0gKipUbToqKiBUZWFtLgoKLSAqKkc6KiogR2FtZXMuCgotICoqTVA6KiogTWludXRlcyBQbGF5ZWQuCgotICoqUEVSOioqIFBsYXllciBFZmZpY2llbmN5IFJhdGluZy4gQSBtZWFzdXJlIG9mIHBlci1taW51dGUgcHJvZHVjdGlvbiBbc3RhbmRhcmRpemVkIHN1Y2ggdGhhdCB0aGUgbGVhZ3VlIGF2ZXJhZ2UgaXMgMTVdey5obH0uCgotICoqVFMlOioqIFRydWUgU2hvb3RpbmcgUGVyY2VudGFnZS4gQSBtZWFzdXJlIG9mIHNob290aW5nIGVmZmljaWVuY3kgdGhhdCB0YWtlcyBpbnRvIGFjY291bnQgMi1wb2ludCBmaWVsZCBnb2FscywgMy1wb2ludCBmaWVsZCBnb2FscywgYW5kIGZyZWUgdGhyb3dzLgoKLSAqKjNQQXI6KiogMy1Qb2ludCBBdHRlbXB0IFJhdGUuIFBlcmNlbnRhZ2Ugb2YgRkcgQXR0ZW1wdHMgZnJvbSAzLVBvaW50IFJhbmdlLgoKLSAqKkZUcjoqKiBGcmVlIFRocm93IEF0dGVtcHQgUmF0ZS4gTnVtYmVyIG9mIEZUIEF0dGVtcHRzIFtQZXIgRkcgQXR0ZW1wdF17LmhsfS4KCi0gKipPUkIlOioqIE9mZmVuc2l2ZSBSZWJvdW5kIFBlcmNlbnRhZ2UuIEFuIGVzdGltYXRlIG9mIHRoZSBwZXJjZW50YWdlIG9mIGF2YWlsYWJsZSBvZmZlbnNpdmUgcmVib3VuZHMgYSBwbGF5ZXIgZ3JhYmJlZCB3aGlsZSB0aGV5IHdlcmUgb24gdGhlIGZsb29yLgoKLSAqKkRSQiU6KiogRGVmZW5zaXZlIFJlYm91bmQgUGVyY2VudGFnZS4gQW4gZXN0aW1hdGUgb2YgdGhlIHBlcmNlbnRhZ2Ugb2YgYXZhaWxhYmxlIGRlZmVuc2l2ZSByZWJvdW5kcyBhIHBsYXllciBncmFiYmVkIHdoaWxlIHRoZXkgd2VyZSBvbiB0aGUgZmxvb3IuCgotICoqVFJCJToqKiBUb3RhbCBSZWJvdW5kIFBlcmNlbnRhZ2UuIEFuIGVzdGltYXRlIG9mIHRoZSBwZXJjZW50YWdlIG9mIGF2YWlsYWJsZSByZWJvdW5kcyBhIHBsYXllciBncmFiYmVkIHdoaWxlIHRoZXkgd2VyZSBvbiB0aGUgZmxvb3IuCgotICoqQVNUJToqKiBBc3Npc3QgUGVyY2VudGFnZS4gQW4gZXN0aW1hdGUgb2YgdGhlIHBlcmNlbnRhZ2Ugb2YgdGVhbW1hdGUgZmllbGQgZ29hbHMgYSBwbGF5ZXIgYXNzaXN0ZWQgd2hpbGUgdGhleSB3ZXJlIG9uIHRoZSBmbG9vci4KCi0gKipTVEwlOioqIFN0ZWFsIFBlcmNlbnRhZ2UuIEFuIGVzdGltYXRlIG9mIHRoZSBwZXJjZW50YWdlIG9mIG9wcG9uZW50IHBvc3Nlc3Npb25zIHRoYXQgZW5kIHdpdGggYSBzdGVhbCBieSB0aGUgcGxheWVyIHdoaWxlIHRoZXkgd2VyZSBvbiB0aGUgZmxvb3IuCgotICoqQkxLJToqKiBCbG9jayBQZXJjZW50YWdlLiBBbiBlc3RpbWF0ZSBvZiB0aGUgcGVyY2VudGFnZSBvZiBvcHBvbmVudCBbdHdvLXBvaW50XXsuaGx9IGZpZWxkIGdvYWwgYXR0ZW1wdHMgYmxvY2tlZCBieSB0aGUgcGxheWVyIHdoaWxlIHRoZXkgd2VyZSBvbiB0aGUgZmxvb3IuCgotICoqVE9WJToqKiBUdXJub3ZlciBQZXJjZW50YWdlLiBBbiBlc3RpbWF0ZSBvZiB0dXJub3ZlcnMgY29tbWl0dGVkIHBlciAxMDAgcGxheXMuCgotICoqVVNHJToqKiBVc2FnZSBQZXJjZW50YWdlLiBBbiBlc3RpbWF0ZSBvZiB0aGUgcGVyY2VudGFnZSBvZiB0ZWFtIHBsYXlzIHVzZWQgYnkgYSBwbGF5ZXIgd2hpbGUgdGhleSB3ZXJlIG9uIHRoZSBmbG9vci4KCi0gKipPV1M6KiogT2ZmZW5zaXZlIFdpbiBTaGFyZXMuIEFuIGVzdGltYXRlIG9mIHRoZSBudW1iZXIgb2Ygd2lucyBjb250cmlidXRlZCBieSBhIHBsYXllciBkdWUgdG8gb2ZmZW5zZS4KCi0gKipEV1M6KiogRGVmZW5zaXZlIFdpbiBTaGFyZXMuIEFuIGVzdGltYXRlIG9mIHRoZSBudW1iZXIgb2Ygd2lucyBjb250cmlidXRlZCBieSBhIHBsYXllciBkdWUgdG8gZGVmZW5zZS4KCi0gKipXUzoqKiBXaW4gU2hhcmVzLiBBbiBlc3RpbWF0ZSBvZiB0aGUgbnVtYmVyIG9mIHdpbnMgY29udHJpYnV0ZWQgYnkgYSBwbGF5ZXIuCgotICoqV1MvNDg6KiogV2luIFNoYXJlcyBQZXIgNDggTWludXRlcy4gQW4gZXN0aW1hdGUgb2YgdGhlIG51bWJlciBvZiB3aW5zIGNvbnRyaWJ1dGVkIGJ5IGEgcGxheWVyIHBlciA0OCBtaW51dGVzIChsZWFndWUgYXZlcmFnZSBpcyBhcHByb3hpbWF0ZWx5IC4xMDApLgoKLSAqKk9CUE06KiogT2ZmZW5zaXZlIEJveCBQbHVzL01pbnVzLiBBIGJveCBzY29yZSBlc3RpbWF0ZSBvZiB0aGUgb2ZmZW5zaXZlIHBvaW50cyBwZXIgMTAwIHBvc3Nlc3Npb25zIGEgcGxheWVyIGNvbnRyaWJ1dGVkIGFib3ZlIGEgbGVhZ3VlLWF2ZXJhZ2UgcGxheWVyLCB0cmFuc2xhdGVkIHRvIGFuIGF2ZXJhZ2UgdGVhbS4KCi0gKipEQlBNOioqIERlZmVuc2l2ZSBCb3ggUGx1cy9NaW51cy4gQSBib3ggc2NvcmUgZXN0aW1hdGUgb2YgdGhlIGRlZmVuc2l2ZSBwb2ludHMgcGVyIDEwMCBwb3NzZXNzaW9ucyBhIHBsYXllciBjb250cmlidXRlZCBhYm92ZSBhIGxlYWd1ZS1hdmVyYWdlIHBsYXllciwgdHJhbnNsYXRlZCB0byBhbiBhdmVyYWdlIHRlYW0uCgotICoqQlBNOioqIEJveCBQbHVzL01pbnVzLiBBIGJveCBzY29yZSBlc3RpbWF0ZSBvZiB0aGUgcG9pbnRzIHBlciAxMDAgcG9zc2Vzc2lvbnMgYSBwbGF5ZXIgY29udHJpYnV0ZWQgYWJvdmUgYSBsZWFndWUtYXZlcmFnZSBwbGF5ZXIsIHRyYW5zbGF0ZWQgdG8gYW4gYXZlcmFnZSB0ZWFtLgoKLSAqKlZPUlA6KiogVmFsdWUgb3ZlciBSZXBsYWNlbWVudCBQbGF5ZXIuIEEgYm94IHNjb3JlIGVzdGltYXRlIG9mIHRoZSBwb2ludHMgcGVyIDEwMCBURUFNIHBvc3Nlc3Npb25zIHRoYXQgYSBwbGF5ZXIgY29udHJpYnV0ZWQgYWJvdmUgYSByZXBsYWNlbWVudC1sZXZlbCAoLTIuMCkgcGxheWVyLCB0cmFuc2xhdGVkIHRvIGFuIGF2ZXJhZ2UgdGVhbSBhbmQgcHJvcmF0ZWQgdG8gYW4gODItZ2FtZSBzZWFzb24uIE11bHRpcGx5IGJ5IDIuNzAgdG8gY29udmVydCB0byB3aW5zIG92ZXIgcmVwbGFjZW1lbnQuCgotICoqUGxheWVyLWFkZGl0aW9uYWw6KiogVW5pcXVlIGlkZW50aWZpZXIuCgoKIyBDbGVhbmluZyB0aGUgZGF0YQoKIyMgUGVyIGdhbWUKCiogRGVsZXRlIGBya2AgY29sdW1uOgoKICAgIGBgYHtyfQogICAgZGZfcGVyX2dhbWUgPC0gCiAgICAgIGRmX3Blcl9nYW1lICU+JSAKICAgICAgICBzZWxlY3QoLXJrKQogICAgYGBgCgoqIFJlbmFtZSBhbGwgY29sdW1uczoKCiAgICBgYGB7cn0KICAgIG9yaWdpbmFsX25hbWVzIDwtIG5hbWVzKGRmX3Blcl9nYW1lKQogICAgbmV3X25hbWVzIDwtIGMoCiAgICAgICdwbGF5ZXInLAogICAgICAncG9zaXRpb24nLAogICAgICAnYWdlJywKICAgICAgJ3RlYW0nLAogICAgICAnZ2FtZXMnLAogICAgICAnZ2FtZXNfc3RhcnRlZCcsCiAgICAgICdtaW51dGVzX3BsYXllZF9hdmVyYWdlJywKICAgICAgJ2dvYWxzX3Njb3JlZCcsCiAgICAgICdnb2FsX2F0dGVtcHRzJywKICAgICAgJ2dvYWxfcGN0JywKICAgICAgJ2dvYWxzX3Njb3JlZF8zcCcsCiAgICAgICdnb2FsX2F0dGVtcHRzXzNwJywKICAgICAgJ2dvYWxfcGN0XzNwJywKICAgICAgJ2dvYWxzX3Njb3JlZF8ycCcsCiAgICAgICdnb2FsX2F0dGVtcHRzXzJwJywKICAgICAgJ2dvYWxfcGN0XzJwJywKICAgICAgJ2dvYWxzX2VmZmVjdGl2ZV9wY3QnLAogICAgICAnZnJlZV90aHJvd3Nfc2NvcmVkJywKICAgICAgJ2ZyZWVfdGhyb3dfYXR0ZW1wdHMnLAogICAgICAnZnJlZV90aHJvd19wY3QnLAogICAgICAncmVib3VuZHNfb2ZmZW5zZScsCiAgICAgICdyZWJvdW5kc19kZWZlbnNlJywKICAgICAgJ3JlYm91bmRzX3RvdGFsJywKICAgICAgJ2Fzc2lzdHMnLAogICAgICAnc3RlYWxzJywKICAgICAgJ2Jsb2NrcycsCiAgICAgICd0dXJub3ZlcnMnLAogICAgICAnZm91bHMnLAogICAgICAncG9pbnRzX3Njb3JlZCcsCiAgICAgICdwbGF5ZXJfaWQnCiAgICApCiAgICAKICAgIG5hbWVzKG5ld19uYW1lcykgPC0gb3JpZ2luYWxfbmFtZXMKICAgIAogICAgcGFzdGUoCiAgICAgIG5hbWVzKG5ld19uYW1lcyksIAogICAgICBuZXdfbmFtZXMsIAogICAgICBzZXAgPSAnIC0+ICcsIAogICAgICBjb2xsYXBzZSA9ICdcbicKICAgICkgJT4lIAogICAgICBjYXQoKQogICAgYGBgCgogICAgYGBge3J9CiAgICBkZl9wZXJfZ2FtZSA8LSBkZl9wZXJfZ2FtZSAlPiUgCiAgICAgIHJlbmFtZV93aXRoKAogICAgICAgIGZ1bmN0aW9uKHgpIHsgbmV3X25hbWVzW3hdIH0KICAgICAgKQogICAgYGBgCgoqIEZpbmQgcGxheWVycyB0aGF0IGFwcGVhciBtb3JlIHRoYW4gb25jZSBhbmQga2VlcCBvbmx5IHRoZSByb3cgdGhhdCBoYXMgdGhlIHRvdGFsczoKCiAgICBgYGB7cn0KICAgIGR1cGVzIDwtIGRmX3Blcl9nYW1lICU+JSAKICAgICAgZ2V0X2R1cGVzKHBsYXllcl9pZCkKICAgIGBgYAoKICBgYGB7cn0KICBkdXBlcyAlPiUgCiAgICBzZWxlY3QocGxheWVyLCB0ZWFtLCBkdXBlX2NvdW50KSAlPiUgCiAgICBhcnJhbmdlKGRlc2MoZHVwZV9jb3VudCkpCiAgYGBgCgogIEZvciB0aGVzZSBwbGF5ZXJzLCB3ZSBrZWVwIG9ubHkgdGhlIHJvdyBmb3IgdGhlIHRvdGFscyAoYFRPVGApOgoKICAgIGBgYHtyfQogICAgZGZfcGVyX2dhbWUgPC0gZGZfcGVyX2dhbWUgJT4lIAogICAgICBrZWVwX29ubHlfdG90YWxzKGR1cGVzKQogICAgYGBgCgoKIyMjIFBlciBnYW1lOiBzdW1tYXJ5CgpgYGB7cn0KZGZfcGVyX2dhbWUgJT4lIAogIGRmU3VtbWFyeShzaWxlbnQgPSBUUlVFKSAlPiUgCiAgcHJpbnQobWV0aG9kID0gJ3JlbmRlcicpCmBgYAoKCiMjIyBQZXIgZ2FtZTogbm90ZXMKCiogQXBwcm94aW1hdGVseSAkMTZcJSQgb2YgcGxheWVycyBwbGF5ZWQgZm9yIHR3byBvciBtb3JlIHRlYW1zIGR1cmluZyB0aGUgc2Vhc29uLgoKKiBPbiBhdmVyYWdlLCBhIHBsYXllciBwbGF5cyBvbmx5ICQxOSQgbWludXRlcyBwZXIgZ2FtZS4KCiogQ29sdW1ucyB0aGF0IHNob3VsZCBjb250YWluIHBlcmNlbnRhZ2VzIGFjdHVhbGx5IGNvbnRhaW4gcHJvcG9ydGlvbnMuCgoqIEFsbCBjb2x1bW5zIHRoYXQgY29udGFpbiBwcm9wb3J0aW9ucyBoYXZlIHNvbWUgbWlzc2luZyB2YWx1ZXMuIEZvcnR1bmF0ZWx5LCBhbGwgb2YgdGhlbSB3aWxsIGJlIGRpc2NhcmRlZCBiZWZvcmUgd2UgYnVpbGQgdGhlIG1vZGVsLCBhcyB0aGV5IGFyZSBkZXJpdmVkIC0tLSB0aGVyZWZvcmUsIHBlcmZlY3RseSBjb3JyZWxhdGVkIHdpdGggb3RoZXIgY29sdW1ucy4KCiogV2hhdCBhcmUgdGhlICJvdGhlciIgcG9zaXRpb25zPwoKICBgYGB7cn0KICBkZl9wZXJfZ2FtZSAlPiUgCiAgICBjb3VudChwb3NpdGlvbiwgc29ydCA9IFRSVUUpICU+JSAKICAgIHNsaWNlX3RhaWwobiA9IDMpCiAgYGBgCgoKIyMjIFBlciBnYW1lOiBtb3JlIGNsZWFuaW5nCgoqIFR1cm4gcHJvcG9ydGlvbnMgaW50byBwZXJjZW50YWdlczoKCiAgICBgYGB7cn0KICAgIGRmX3Blcl9nYW1lIDwtIGRmX3Blcl9nYW1lICU+JSAKICAgICAgbXV0YXRlKAogICAgICAgIGFjcm9zcyhjb250YWlucygnX3BjdCcpLCB+IC54ICogMTAwKQogICAgICApCiAgICBgYGAKCiogV2h5IGFyZSBzb21lIHBlcmNlbnRhZ2VzIGBOQWA/CgogIGBgYHtyfQogIGRmX3Blcl9nYW1lICU+JSAKICAgIGZpbHRlcihpcy5uYShnb2FsX3BjdCkpICU+JSAKICAgIHNlbGVjdChzdGFydHNfd2l0aCgnZ29hbCcpKQogIGBgYAogIAogIEJlY2F1c2UgdGhleSBhcmUgJDBcJSQgb2YgJDAkLgogIAogIEkgd2lsbCByZXBsYWNlIHRoZSBgTkFgcyB3aXRoIHplcm9lczoKICAKICAgIGBgYHtyfQogICAgZGZfcGVyX2dhbWUgPC0gZGZfcGVyX2dhbWUgJT4lIAogICAgICBtdXRhdGUoCiAgICAgICAgYWNyb3NzKAogICAgICAgICAgY29udGFpbnMoJ19wY3QnKSwKICAgICAgICAgIH4gaWZfZWxzZSgKICAgICAgICAgICAgaXMubmEoLngpLCAwLCAueAogICAgICAgICAgKQogICAgICAgICkKICAgICAgKQogICAgYGBgCiAgCgojIyMgUGVyIGdhbWU6IGFub3RoZXIgc3VtbWFyeQoKYGBge3J9CmRmX3Blcl9nYW1lICU+JSAKICBkZlN1bW1hcnkoc2lsZW50ID0gVFJVRSkgJT4lIAogIHByaW50KG1ldGhvZCA9ICdyZW5kZXInKQpgYGAKCgojIyBBZHZhbmNlZAoKKiBEZWxldGUgYHJrYCBjb2x1bW46CgogICAgYGBge3J9CiAgICBkZl9hZHZhbmNlZCA8LSAKICAgICAgZGZfYWR2YW5jZWQgJT4lIAogICAgICAgIHNlbGVjdCgtcmspCiAgICBgYGAKCiogUmVuYW1lIGFsbCBjb2x1bW5zOgoKICAgIGBgYHtyfQogICAgb3JpZ2luYWxfbmFtZXMgPC0gbmFtZXMoZGZfYWR2YW5jZWQpCiAgICBuZXdfbmFtZXMgPC0gYygKICAgICAgJ3BsYXllcicsCiAgICAgICdwb3NpdGlvbicsCiAgICAgICdhZ2UnLAogICAgICAndGVhbScsCiAgICAgICdnYW1lcycsCiAgICAgICdtaW51dGVzX3BsYXllZF90b3RhbCcsCiAgICAgICdlZmZpY2llbmN5JywKICAgICAgJ3RydWVfc2hvb3RpbmdfcGN0JywKICAgICAgJ2F0dGVtcHRfcmF0ZV8zcCcsCiAgICAgICdhdHRlbXB0X3JhdGVfZnJlZV90aHJvdycsCiAgICAgICdyZWJvdW5kX29mZmVuc2VfcGN0JywKICAgICAgJ3JlYm91bmRfZGVmZW5zZV9wY3QnLAogICAgICAncmVib3VuZF90b3RhbF9wY3QnLAogICAgICAnYXNzaXN0X3BjdCcsCiAgICAgICdzdGVhbF9wY3QnLAogICAgICAnYmxvY2tfcGN0JywKICAgICAgJ3R1cm5vdmVyX3BjdCcsCiAgICAgICd1c2FnZV9wY3QnLAogICAgICAnd2luX3NoYXJlc19vZmZlbnNlJywKICAgICAgJ3dpbl9zaGFyZXNfZGVmZW5zZScsCiAgICAgICd3aW5fc2hhcmVzJywKICAgICAgJ3dpbl9zaGFyZXNfNDgnLAogICAgICAncGx1c19taW51c19vZmZlbnNlJywKICAgICAgJ3BsdXNfbWludXNfZGVmZW5zZScsCiAgICAgICdwbHVzX21pbnVzJywKICAgICAgJ3ZhbHVlX292ZXJfcmVwbGFjZW1lbnQnLAogICAgICAncGxheWVyX2lkJwogICAgKQogICAgCiAgICBuYW1lcyhuZXdfbmFtZXMpIDwtIG9yaWdpbmFsX25hbWVzCiAgICAKICAgIHBhc3RlKAogICAgICBuYW1lcyhuZXdfbmFtZXMpLCAKICAgICAgbmV3X25hbWVzLCAKICAgICAgc2VwID0gJyAtPiAnLCAKICAgICAgY29sbGFwc2UgPSAnXG4nCiAgICApICU+JSAKICAgICAgY2F0KCkKICAgIGBgYAoKICAgIGBgYHtyfQogICAgZGZfYWR2YW5jZWQgPC0gZGZfYWR2YW5jZWQgJT4lIAogICAgICByZW5hbWVfd2l0aCgKICAgICAgICBmdW5jdGlvbih4KSB7IG5ld19uYW1lc1t4XSB9CiAgICAgICkKICAgIGBgYAoKKiBGaW5kIHBsYXllcnMgdGhhdCBhcHBlYXIgbW9yZSB0aGFuIG9uY2UgYW5kIGtlZXAgb25seSB0aGUgcm93IHRoYXQgaGFzIHRoZSB0b3RhbHM6CgogICAgYGBge3J9CiAgICBkdXBlcyA8LSBkZl9hZHZhbmNlZCAlPiUgCiAgICAgIGdldF9kdXBlcyhwbGF5ZXJfaWQpCiAgICBgYGAKCiAgYGBge3J9CiAgZHVwZXMgJT4lIAogICAgc2VsZWN0KHBsYXllciwgdGVhbSwgZHVwZV9jb3VudCkgJT4lIAogICAgYXJyYW5nZShkZXNjKGR1cGVfY291bnQpKQogIGBgYAoKICBGb3IgdGhlc2UgcGxheWVycywgd2Uga2VlcCBvbmx5IHRoZSByb3cgZm9yIHRoZSB0b3RhbHMgKGBUT1RgKToKCiAgICBgYGB7cn0KICAgIGRmX2FkdmFuY2VkIDwtIGRmX2FkdmFuY2VkICU+JSAKICAgICAga2VlcF9vbmx5X3RvdGFscyhkdXBlcykKICAgIGBgYAoKCiMjIyBBZHZhbmNlZDogc3VtbWFyeQoKYGBge3J9CmRmX2FkdmFuY2VkICU+JSAKICBkZlN1bW1hcnkoc2lsZW50ID0gVFJVRSkgJT4lIAogIHByaW50KG1ldGhvZCA9ICdyZW5kZXInKQpgYGAKCgojIyMgQWR2YW5jZWQ6IG5vdGVzCgoqIEhlcmUsIHBlcmNlbnRhZ2VzIGFyZSByZWFsbHkgcGVyY2VudGFnZXMgKGJldHdlZW4gJDAkIGFuZCAkMTAwJCksIFtleGNlcHQgZm9yIGB0cnVlX3Nob290aW5nX3BjdGBdey5obH0uIAoKKiBPZmZlbnNpdmUgcmVib3VuZHMgYXJlIGhhcmRlciB0aGFuIGRlZmVuc2l2ZSByZWJvdW5kcy4KCiogTW9zdCBzdGF0aXN0aWNzIGhlcmUgaGF2ZSByaWdodC1za2V3ZWQgZGlzdHJpYnV0aW9ucy4KCiogV2hhdCBhcmUgdGhlICJvdGhlciIgcG9zaXRpb25zPwoKICBgYGB7cn0KICBkZl9hZHZhbmNlZCAlPiUgCiAgICBjb3VudChwb3NpdGlvbiwgc29ydCA9IFRSVUUpICU+JSAKICAgIHNsaWNlX3RhaWwobiA9IDMpCiAgYGBgCgoqIEFyZSB0aGUgcGxheWVycyBpbiB0aGUgYGFkdmFuY2VkYCBkYXRhIGZyYW1lIHRoZSBzYW1lIGFzIGluIHRoZSBgcGVyIGdhbWVgIGRhdGEgZnJhbWU/CgogIGBgYHtyfQogIGlkZW50aWNhbCgKICAgIHNvcnQoZGZfcGVyX2dhbWUkcGxheWVyX2lkKSwKICAgIHNvcnQoZGZfYWR2YW5jZWQkcGxheWVyX2lkKQogICkKICBgYGAKCiMjIyBBZHZhbmNlZDogbW9yZSBjbGVhbmluZwoKKiBGaXggYHRydWVfc2hvb3RpbmdfcGN0YDoKCiAgICBgYGB7cn0KICAgIGRmX2FkdmFuY2VkIDwtIGRmX2FkdmFuY2VkICU+JSAKICAgICAgbXV0YXRlKHRydWVfc2hvb3RpbmdfcGN0ID0gMTAwICogdHJ1ZV9zaG9vdGluZ19wY3QpCiAgICBgYGAKCiogUmVwbGFjZSB0aGUgYE5BYHMgd2l0aCB6ZXJvZXM6CiAgCiAgICBgYGB7cn0KICAgIGRmX2FkdmFuY2VkIDwtIGRmX2FkdmFuY2VkICU+JSAKICAgICAgbXV0YXRlKAogICAgICAgIGFjcm9zcygKICAgICAgICAgIC5mbnMgPSAKICAgICAgICAgICAgfiBpZiAoaXMubnVtZXJpYygueCkpIHsKICAgICAgICAgICAgICAgIGlmX2Vsc2UoaXMubmEoLngpLCAwLCAueCkKICAgICAgICAgICAgfSBlbHNlIHsgLnggfQogICAgICAgICkKICAgICAgKQogICAgYGBgCgoKIyMjIEFkdmFuY2VkOiBhbm90aGVyIHN1bW1hcnkKCmBgYHtyfQpkZl9hZHZhbmNlZCAlPiUgCiAgZGZTdW1tYXJ5KHNpbGVudCA9IFRSVUUpICU+JSAKICBwcmludChtZXRob2QgPSAncmVuZGVyJykKYGBgCgoK