`group_by()` is a dplyr function that divides a tabular data set into groups defined by one or more variables. Functions placed later in a pipe can then calculate results separately for each group rather than across every row at once. This turns questions such as “Which draft years produced the most win shares?” into a compact workflow. section 2.5.3 section 4.5.4
A useful reading rule is: group first, then summarize. Without grouping, `summarize(mean(WS))` returns one overall career-win-shares average. With `group_by(Year)`, the same summary returns one average for each draft year. The output is commonly a tibble, which can become the input for a chart or another wrangling step. section 2.5.3 section 2.5.5
Average win shares by draft year
```r draft %>% group_by(Year) %>% summarize(avg = mean(WS)) ``` `Year` supplies the groups, and `summarize()` calculates `mean(WS)` within each one. The result has one row per year, letting you compare draft classes instead of treating all players as one pool. section 2.5.3
Grouping is not limited to a single category. Supply several variables to define combinations, such as position, birthplace, and college attendance. Each distinct combination receives its own mean and median. This is helpful when a broad comparison hides meaningful differences between smaller segments. section 2.5.5
Common patterns pair `group_by()` with later verbs:
- `tally()` counts rows in each group, such as free agents by position or play-by-play events by event type. section 4.5.4 section 8.4
- `summarize()` produces group-level statistics, including means, medians, totals, and counts. section 2.5.5 section 18.4.4
- `mutate()` creates values relative to each group, such as a player's rank within a season and team or deviations from a seasonal mean. section 12.4 section 18.4.4
- `slice()` keeps selected rows per group, such as the scoring leader in each year or all but the first event in each game. section 19.4 section 16.4.2
Order matters. Filter first when only a subset belongs in the calculation, then group and summarize it. For example, filtering players with at least 75 win shares before grouping by draft year produces average draft position only for that high-win-share subset. Grouping can also support cleaning: matching player, season, and position identifies records that must be aggregated after total-team rows are removed. section 2.5.3 section 19.3.1
Rank players within each team-season
```r ws_gini %>% arrange(Year, Tm, WS) %>% group_by(Year, Tm) %>% mutate(rank = rank(-WS, ties.method = "first")) %>% filter(rank <= 14) ``` Here the rank restarts for every `Year` and `Tm` combination. Descending `WS` gives the highest win shares rank 1; filtering then retains no more than 14 players from each team-season. section 13.3
draft %>% group_by(Year) %>% summarize(avg = mean(WS)) -> second_tibble print(second_tibble) ## # A tibble: 10 × 2 ## Year avg ## <fct> <dbl> ## 1 2000 18.3 ## 2 2001 39.0 ## 3 2002 21.4 ## 4 2003 37.9 ## 5 2004 34.0 ## 6 2005 30.6 ## 7 2006 20.6 ## 8 2007 28.6 ## 9 2008 33.7 ## 10 2009 29.6
Inspect the grouped yearly summary: each row is a separate draft year with its own mean career win shares, rather than one overall mean. section 2.5.3
