knitr::opts_chunk$set(echo = TRUE)
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ ggplot2 3.4.0 ✔ purrr 1.0.1
## ✔ tibble 3.1.8 ✔ dplyr 1.0.10
## ✔ tidyr 1.3.0 ✔ stringr 1.5.0
## ✔ readr 2.1.3 ✔ forcats 1.0.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
library(ggplot2)
# create datasets
bowling_scores <- read.csv("bowling_scores.csv")
connor_data <- filter(bowling_scores, player == "connor")
seth_data <- filter(bowling_scores, player == "seth")
rebecca_data <- filter(bowling_scores, player == "rebecca")
garrett_data <- filter(bowling_scores, player == "garrett")
# full bowling graph
ggplot(bowling_scores, aes(x = game, y = score, color = player, group = player)) +
geom_line(size = 1) +
geom_point(size = 1.5) +
geom_text(aes(label = format(score)),
hjust = -0.1, vjust = -0.5, size = 3, check_overlap = TRUE) +
labs(title = "Bowling Scores Summer 2K24",
x = "Game",
y = "Score") +
theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.

# find extrema points
find_local_extrema <- function(df) {
df %>%
group_by(player) %>%
mutate(
local_max = score == max(score), # Identify local maximum
local_min = score == min(score) # Identify local minimum
) %>%
filter(local_max | local_min) # Keep only max or min points
}
extrema_points <- find_local_extrema(bowling_scores)
print(extrema_points)
## # A tibble: 29 × 9
## # Groups: player [15]
## game date player score round splits strikes local_max local_min
## <int> <dbl> <chr> <int> <int> <int> <chr> <lgl> <lgl>
## 1 2 5.24 daniel 102 2 1 "" TRUE FALSE
## 2 2 5.24 emilee 51 2 0 "" FALSE TRUE
## 3 6 5.29 daniel 48 2 1 "" FALSE TRUE
## 4 6 5.29 rebecca 32 2 0 "" FALSE TRUE
## 5 7 5.3 derek 65 1 0 "" FALSE TRUE
## 6 8 5.3 derek 90 2 0 "" TRUE FALSE
## 7 8 5.3 kiana 125 2 1 "" TRUE FALSE
## 8 13 6.03 rebecca 128 2 2 "" TRUE FALSE
## 9 16 6.08 wyatt 129 1 0 "" TRUE FALSE
## 10 16 6.08 kiana 73 1 1 "" FALSE TRUE
## # ℹ 19 more rows
# bowling graph with extrema labels only
ggplot(bowling_scores, aes(x = game, y = score, color = player, group = player)) +
geom_line(size = .9) +
geom_point(size = 1) +
geom_text(data = extrema_points, aes(label = score), vjust = -.25, hjust = -.25, size = 2.5) +
labs(title = "Bowling Scores Summer 2K24",
x = "Game",
y = "Score") +
theme_minimal()

# average scores by player
average_scores <- bowling_scores %>%
group_by(player) %>%
summarize(average_score = mean(score))
print(average_scores)
## # A tibble: 15 × 2
## player average_score
## <chr> <dbl>
## 1 anika 68
## 2 connor 132.
## 3 daniel 74
## 4 derek 77.5
## 5 elaine 68
## 6 emilee 84.3
## 7 garrett 41
## 8 kiana 97.8
## 9 neha 58
## 10 noah 103.
## 11 quynh 87.5
## 12 rebecca 74.6
## 13 rishabh 103
## 14 seth 95.3
## 15 wyatt 114.
# average scores by player by round
average_scores_by_round <- bowling_scores %>%
group_by(player, round) %>%
summarize(average_score = mean(score)) %>%
ungroup()
## `summarise()` has grouped output by 'player'. You can override using the
## `.groups` argument.
print(average_scores_by_round)
## # A tibble: 32 × 3
## player round average_score
## <chr> <int> <dbl>
## 1 anika 1 68
## 2 connor 1 130.
## 3 connor 2 134.
## 4 connor 3 125
## 5 connor 4 131
## 6 daniel 1 73.3
## 7 daniel 2 75
## 8 derek 1 65
## 9 derek 2 90
## 10 elaine 1 81
## # ℹ 22 more rows
# average splits
average_splits <- bowling_scores %>%
group_by(player) %>%
summarize(average_splits = mean(splits, na.rm = T))
print(average_splits)
## # A tibble: 15 × 2
## player average_splits
## <chr> <dbl>
## 1 anika 1
## 2 connor 0.962
## 3 daniel 1.2
## 4 derek 0
## 5 elaine 1.67
## 6 emilee 1.09
## 7 garrett 0.833
## 8 kiana 1.75
## 9 neha 0
## 10 noah 1
## 11 quynh 1.38
## 12 rebecca 0.961
## 13 rishabh 0.75
## 14 seth 0.5
## 15 wyatt 0.5
# average score by number of splits
average_score_split <- bowling_scores %>%
group_by(splits) %>%
summarize(average_score = mean(score))
print(average_score_split)
## # A tibble: 7 × 2
## splits average_score
## <int> <dbl>
## 1 0 93.5
## 2 1 97.4
## 3 2 89.3
## 4 3 80.7
## 5 4 101
## 6 5 98
## 7 NA 154.
#overall average score
overall_avg <- mean(bowling_scores$score)
print(overall_avg)
## [1] 95.18056
# linear model, score as a function of splits
summary(lm(score ~ splits, data = bowling_scores))
##
## Call:
## lm(formula = score ~ splits, data = bowling_scores)
##
## Residuals:
## Min 1Q Median 3Q Max
## -63.292 -21.648 -3.108 25.168 77.076
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 95.292 2.923 32.60 <2e-16 ***
## splits -1.368 2.243 -0.61 0.543
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 30.9 on 210 degrees of freedom
## (4 observations deleted due to missingness)
## Multiple R-squared: 0.001768, Adjusted R-squared: -0.002986
## F-statistic: 0.3719 on 1 and 210 DF, p-value: 0.5426
# score by splits scatterplot (color = player)
ggplot(bowling_scores, aes(x= splits, y=score, color = player)) +
geom_point()
## Warning: Removed 4 rows containing missing values (`geom_point()`).

# score by splits scatterplot with best fit line
ggplot(bowling_scores, aes(x= splits, y=score)) +
geom_point() +
geom_smooth(method = "lm")
## `geom_smooth()` using formula = 'y ~ x'
## Warning: Removed 4 rows containing non-finite values (`stat_smooth()`).
## Warning: Removed 4 rows containing missing values (`geom_point()`).

#scores histogram
ggplot(bowling_scores, aes(x = score, color = player)) +
geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

#score by game scatterplot with best fit line
ggplot(bowling_scores, aes(x= game, y=score)) +
geom_point() +
geom_smooth(method = "lm")
## `geom_smooth()` using formula = 'y ~ x'

#score by game linear model
summary(lm(score ~ game, data = bowling_scores))
##
## Call:
## lm(formula = score ~ game, data = bowling_scores)
##
## Residuals:
## Min 1Q Median 3Q Max
## -65.323 -23.737 -3.016 22.415 83.819
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 84.0967 4.2217 19.920 < 2e-16 ***
## game 0.3742 0.1231 3.039 0.00267 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 31.25 on 214 degrees of freedom
## Multiple R-squared: 0.04137, Adjusted R-squared: 0.03689
## F-statistic: 9.236 on 1 and 214 DF, p-value: 0.002669
# mean score by game
mean_by_game <- bowling_scores %>%
group_by(game) %>%
summarize(mean_score = mean(score))
print(mean_by_game)
## # A tibble: 65 × 2
## game mean_score
## <int> <dbl>
## 1 1 75.4
## 2 2 75.4
## 3 3 61
## 4 4 73
## 5 5 88.8
## 6 6 73.8
## 7 7 87.4
## 8 8 110.
## 9 9 101
## 10 10 99
## # ℹ 55 more rows
# overall bowling graph with adaptive mean line
ggplot(bowling_scores, aes(x = game, y = score, color = player, group = player)) +
geom_line(size = 1) +
geom_point(size = 1.5) +
geom_text(aes(label = format(score)),
hjust = -0.1, vjust = -0.5, size = 3, check_overlap = TRUE) +
geom_hline(yintercept = overall_avg, linetype = "dashed", color = "red", size = 1) +
labs(title = "Bowling Scores Summer 2K24",
x = "Game",
y = "Score") +
theme_minimal()

# number of games played by player
games_played <- bowling_scores %>%
group_by(player) %>%
summarize(num_games = n())
print(games_played)
## # A tibble: 15 × 2
## player num_games
## <chr> <int>
## 1 anika 1
## 2 connor 56
## 3 daniel 5
## 4 derek 2
## 5 elaine 3
## 6 emilee 11
## 7 garrett 12
## 8 kiana 8
## 9 neha 1
## 10 noah 4
## 11 quynh 8
## 12 rebecca 51
## 13 rishabh 4
## 14 seth 48
## 15 wyatt 2
#connor graph
ggplot(connor_data, aes(x = game, y = score, color = player, group = player)) +
geom_line(size = 1) +
geom_point(size = 1.5) +
geom_text(aes(label = format(score)),
hjust = -0.1, vjust = -0.5, size = 3, check_overlap = TRUE) +
labs(title = "Bowling Scores Summer 2K24",
x = "Game",
y = "Score") +
geom_smooth() +
theme_minimal()
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

ggplot(connor_data, aes(x = game, y = score, color = player, group = player)) +
geom_line(size = 1) +
geom_point(size = 1.5) +
geom_text(aes(label = format(score)),
hjust = -0.1, vjust = -0.5, size = 3, check_overlap = TRUE) +
labs(title = "Bowling Scores Summer 2K24",
x = "Game",
y = "Score") +
geom_smooth(method = "lm") +
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

# rebecca graph
ggplot(rebecca_data, aes(x = game, y = score, color = player, group = player)) +
geom_line(size = 1) +
geom_point(size = 1.5) +
geom_text(aes(label = format(score)),
hjust = -0.1, vjust = -0.5, size = 3, check_overlap = TRUE) +
labs(title = "Bowling Scores Summer 2K24",
x = "Game",
y = "Score") +
geom_smooth() +
theme_minimal()
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

ggplot(rebecca_data, aes(x = game, y = score, color = player, group = player)) +
geom_line(size = 1) +
geom_point(size = 1.5) +
geom_text(aes(label = format(score)),
hjust = -0.1, vjust = -0.5, size = 3, check_overlap = TRUE) +
labs(title = "Bowling Scores Summer 2K24",
x = "Game",
y = "Score") +
geom_smooth(method = "lm") +
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

# my graph
ggplot(seth_data, aes(x = game, y = score, color = player, group = player)) +
geom_line(size = 1) +
geom_point(size = 1.5) +
geom_text(aes(label = format(score)),
hjust = -0.1, vjust = -0.5, size = 3, check_overlap = TRUE) +
labs(title = "Bowling Scores Summer 2K24",
x = "Game",
y = "Score") +
geom_smooth() +
theme_minimal()
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

ggplot(seth_data, aes(x = game, y = score, color = player, group = player)) +
geom_line(size = 1) +
geom_point(size = 1.5) +
geom_text(aes(label = format(score)),
hjust = -0.1, vjust = -0.5, size = 3, check_overlap = TRUE) +
labs(title = "Bowling Scores Summer 2K24",
x = "Game",
y = "Score") +
geom_smooth(method = "lm") +
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

ggplot(garrett_data, aes(x = game, y = score, color = player, group = player)) +
geom_line(size = 1) +
geom_point(size = 1.5) +
geom_text(aes(label = format(score)),
hjust = -0.1, vjust = -0.5, size = 3, check_overlap = TRUE) +
labs(title = "Bowling Scores Summer 2K24",
x = "Game",
y = "Score") +
geom_smooth() +
theme_minimal()
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

## real ones only graph
bowling_scores_lil <- bowling_scores %>%
filter(player %in% c("seth", "connor", "rebecca", "emilee", "garrett"))
ggplot(bowling_scores_lil, aes(x = game, y = score, color = player, group = player)) +
geom_line(size = .9) +
geom_point(size = 1) +
geom_text(aes(label = format(score)),
hjust = -0.1, vjust = -0.5, size = 2.5, check_overlap = TRUE) +
labs(title = "Bowling Scores Summer 2K24",
x = "Game",
y = "Score") +
theme_minimal() +
geom_smooth(method = lm, se = FALSE, linetype = "dashed", size = 1)
## `geom_smooth()` using formula = 'y ~ x'

find_local_extrema <- function(df) {
df %>%
group_by(player) %>%
mutate(
local_max = score == max(score), # Identify local maximum
local_min = score == min(score) # Identify local minimum
) %>%
filter(local_max | local_min) # Keep only max or min points
}
extrema_points_lil <- find_local_extrema(bowling_scores_lil)
ggplot(bowling_scores_lil, aes(x = game, y = score, color = player, group = player)) +
geom_line(size = .9) +
geom_point(size = 1) +
geom_text(data = extrema_points_lil, aes(label = score), vjust = -.25, hjust = -.25, size = 2.5) +
labs(title = "Bowling Scores Summer 2K24",
x = "Game",
y = "Score") +
theme_minimal() +
geom_smooth(method = lm, se = FALSE, linetype = "dashed", size = 1)
## `geom_smooth()` using formula = 'y ~ x'
