We like creating content with R Markdown (like this entire site!). It makes it easy to write one-off posts like these and also opens the door for automated reporting. The challenge is crafting dynamic text that sounds natural.
One simple tool to help comes from the toOrdinal package in R. It turns
2nd to make describing relative position data a breeze.
Imagine we have data from ten runners showing the time is took in seconds to complete a 100-meter race. We can add rank for where they finished with
min_rank() from tidyverse/dplyr.
library(tidyverse) library(knitr) set.seed(123) runners <- 10 results <- data.frame(lane = 1:runners, time = rnorm(runners, 11, .5)) results <- results %>% mutate(place = min_rank(time)) kable(results)
Say you want to write the runner in lane x completed the race in y seconds, finishing in z place. Focusing on the runner in lane four, we could write:
one_runner <- results %>% filter(lane == 4) my_text <- str_c("The runner in lane ", one_runner$lane, " completed the race in ", round(one_runner$time,2), # rounding the result for display purposes " seconds, finishing in ", one_runner$place, " place.")
The runner in lane 4 completed the race in 11.04 seconds, finishing in 6 place.
toOrdinal() function from the package with the same name, we swap out the awkward sounding “6 place” with the more natural “6th place”. This is an especially helpful transformation as it isn’t easy to write clear text rules for all possible integer values.
my_text_clean <- str_c("The runner in lane ", one_runner$lane, " completed the race in ", round(one_runner$time,2), " seconds, finishing in ", toOrdinal(one_runner$place), # added the toOrdinal function around the place variable " place.")
The runner in lane 4 completed the race in 11.04 seconds, finishing in 6th place.
##  "1st"
##  "23rd"
##  "147th"