tidy_report.R in R
A whole tidyverse pipeline: read, clean, reshape, model per group, plot.
suppressPackageStartupMessages({
library(dplyr)
library(tidyr)
library(readr)
library(purrr)
library(stringr)
library(ggplot2)
})
RAW <- "session,lang,chars,seconds,errors
1,r,1520,60,4
2,r,1680,60,3
3,r,1810,60,2
4,r,1900,60,2
1,python,1740,60,5
2,python,1880,60,3
3,python,2010,60,1
4,python,2120,60,1
1,sql,1180,60,6
2,sql,1240,60,4
3,sql,1310,60,3
"
runs <- read_csv(RAW, show_col_types = FALSE) |>
mutate(
wpm = (chars / 5) / (seconds / 60),
accuracy = (1 - errors / chars) * 100,
lang = str_to_title(lang)
)
cat("--- per language ---\n")
summary_table <- runs |>
summarise(
sessions = n(),
best_wpm = max(wpm),
mean_wpm = mean(wpm),
mean_accuracy = mean(accuracy),
.by = lang
) |>
arrange(desc(mean_wpm)) |>
mutate(across(where(is.numeric), \(x) round(x, 1)))
print(summary_table)
cat("\n--- improvement per session ---\n")
slopes <- runs |>
nest(.by = lang) |>
mutate(
model = map(data, \(d) lm(wpm ~ session, data = d)),
per_session = map_dbl(model, \(m) coef(m)[["session"]]),
r_squared = map_dbl(model, \(m) summary(m)$r.squared)
) |>
select(lang, per_session, r_squared) |>
mutate(across(where(is.numeric), \(x) round(x, 3)))
print(slopes)
cat("\n--- wide view ---\n")
print(runs |>
select(lang, session, wpm) |>
mutate(wpm = round(wpm)) |>
pivot_wider(names_from = session, values_from = wpm,
names_prefix = "s"))
plot <- runs |>
ggplot(aes(session, wpm, colour = lang)) +
geom_point(size = 2) +
geom_smooth(method = "lm", formula = y ~ x, se = FALSE, linewidth = 0.8) +
scale_x_continuous(breaks = 1:4) +
labs(title = "Words per minute by session", x = "session", y = "wpm") +
theme_minimal()
out <- tempfile(fileext = ".png")
ggsave(out, plot, width = 6, height = 3.5, dpi = 120)
cat("\nwrote", basename(out), "\n")
How it works
- Every stage is a verb in one pipeline, with no stray variables.
- The per-group model lives in a list column.
- The plot comes off the end of the same pipeline.
Keywords and builtins used here
acrossaesarrangebasenamecatcoefdescgeom_pointgeom_smoothggplotggsavelabslibrarylmmapmap_dblmaxmeanmutatennestpivot_widerprintread_csvroundscale_x_continuousselectstr_to_titlesummarisesummarysuppressPackageStartupMessagestempfiletheme_minimalwhere
The run, in numbers
- Lines
- 73
- Characters to type
- 1736
- Tokens
- 441
- Three-star pace
- 110 tpm
At the three-star pace of 110 tokens a minute, this run takes about 241 seconds.
Step 1 of 1 in Encore, step 12 of 12 in Reshaping & reading.