escapeR is a small
escape-room game for learning R through ecological statistics. Each room
gives you a thread of the whole story, a task, and a lock. You solve the
task with ordinary R commands, then submit the answer to move to the
next room.
The bundled quest starts with R foundations and moves through data import, visualisation, data manipulation, simple ecological modelling, distance-sampling ideas, and reproducible workflows.
To start playing you simply need to load the package and call
escape():
In an interactive R session, escape() asks for your
player name. Use a short name you can remember, because
escapeR saves your progress under that name. For a new
player, omitting the escape argument starts the built-in
foundations sequence. A returning player instead resumes
whichever sequence is saved in that profile. The
foundations sequence begins with the console
room and then moves through the package’s core R and
ecological-statistics rooms. You can also name it explicitly:
You can also provide your player name directly:
The first room is then printed in the console. It includes:
The task is solved outside the game prompt. Use R as you normally would: create objects, inspect data, calculate values, make plots, or fit models. When you think you have the answer, submit it.
Use submit() with the answer that should open the
current lock:
If the answer is correct, escapeR shows the success
message and moves you to the next room. If the answer is not correct,
the room remains locked and you can try again.
While numeric answers are submitted as is, text answers should be submitted as character strings:
For simple text locks, escapeR ignores leading and
trailing spaces and is not case-sensitive. Numeric answers are checked
with a small tolerance unless a room uses a custom checker.
If you get stuck, call hint():
Some rooms have more than one hint. Repeated calls reveal the hints in order:
Hints are meant to nudge you toward the R idea rather than simply giving away the answer. In a classroom, it is usually worth trying the task first, asking R what objects you have created, and then requesting a hint if the lock is still not opening.
If the console has filled up with other work, call
play():
play() does not restart the game. It simply prints the
current room again, so you can reread the task and learning goal.
Use status() to see where you are:
This tells you the active player, how many rooms have been solved out of those in the game, and which room is current. It is useful during longer activities or when returning to the game after a break.
Progress is saved automatically for each player using
tools::R_user_dir("escapeR", "data"). To resume, load the
package and call escape() again with the same player
name:
If saved progress exists for that player, the game resumes from the current room. If no saved progress exists, a new quest starts.
To restart the active player’s quest from the beginning, call:
You can also reset a named player:
Or start again directly with escape(reset = TRUE):
Use resetting with care in class: it deliberately starts that player’s progress again from room 1, so all previous progress is lost.
Several rooms ask you to read or inspect files included with the
package. Use escapeR_file() to find them. As an example, if
a data file was called “dataX.csv” you would use
For example, a room might ask you to read a CSV file and then inspect it. One option would then be
The package also provides a separate, small survey data set.
survey_counts() returns this data frame directly; it does
not read or modify dados1.csv. Store the returned data
frame in an object before working with it:
survey <- survey_counts()
names(survey)
#> [1] "site" "habitat" "count" "distance_m" "detected"
head(survey)
#> site habitat count distance_m detected
#> 1 S1 forest 12 15 TRUE
#> 2 S2 forest 15 40 TRUE
#> 3 S3 forest 11 70 TRUE
#> 4 S4 forest 14 95 FALSE
#> 5 S5 scrub 6 20 TRUE
#> 6 S6 scrub 9 55 TRUE
sum(is.na(survey))
#> [1] 2It has five named columns (site, habitat,
count, distance_m, and detected).
Two values in count are NA, included
deliberately for the data quality exercise. By contrast,
dados1.csv has four columns and no missing values. The
survey data set appears in several rooms about data quality, summaries,
modelling, and distance sampling.
Use list_rooms() to inspect the bundled room
sequence:
list_rooms()
#> room id
#> console 1 console
#> vector 2 vector
#> finddata 3 finddata
#> datatab 4 datatab
#> columns 5 columns
#> missing 6 missing
#> plotwin 7 plotwin
#> habitat 8 habitat
#> hidden 9 hidden
#> subset 10 subset
#> sorting 11 sorting
#> model 12 model
#> resid 13 resid
#> predict 14 predict
#> detectp 15 detectp
#> detect 16 detect
#> trunc 17 trunc
#> comment 18 comment
#> webglm 19 webglm
#> quarto 20 quarto
#> en08 21 en08
#> en09 22 en09
#> en10 23 en10
#> en11 24 en11
#> en12 25 en12
#> en13 26 en13
#> en14 27 en14
#> en15 28 en15
#> en16 29 en16
#> en17 30 en17
#> en18 31 en18
#> en19 32 en19
#> en20 33 en20
#> en21 34 en21
#> en22 35 en22
#> en23 36 en23
#> en24 37 en24
#> en01 38 en01
#> en25 39 en25
#> en02 40 en02
#> en03 41 en03
#> en04 42 en04
#> en05 43 en05
#> en06 44 en06
#> en07 45 en07
#> module
#> console R foundations
#> vector R foundations
#> finddata Data import and inspection
#> datatab Data import and inspection
#> columns Data import and inspection
#> missing Data import and inspection
#> plotwin Visualisation
#> habitat Visualisation
#> hidden Visualisation
#> subset Data manipulation
#> sorting Data manipulation
#> model Ecological modelling
#> resid Ecological modelling
#> predict Ecological modelling
#> detectp Distance sampling
#> detect Distance sampling
#> trunc Distance sampling
#> comment Reproducible workflow
#> webglm Reproducible workflow
#> quarto Reproducible workflow
#> en08 Ecologia Numérica - Lecture 08: Experimental design and pseudoreplication
#> en09 Ecologia Numérica - Lecture 09: Exploratory graphics and transformations
#> en10 Ecologia Numérica - Lecture 10: Hypothesis testing and p-values
#> en11 Ecologia Numérica - Lecture 11: Assumptions and the one-sample t-test
#> en12 Ecologia Numérica - Lecture 12: One- and two-sample tests: signed ranks
#> en13 Ecologia Numérica - Lecture 13: Paired tests and one-way ANOVA
#> en14 Ecologia Numérica - Lecture 14: Multiple comparisons and factorial ANOVA
#> en15 Ecologia Numérica - Lecture 15: Blocks, repeated measures, and nested designs
#> en16 Ecologia Numérica - Lecture 16: Simple and multiple linear regression
#> en17 Ecologia Numérica - Lecture 17: Factors in regression and model diagnostics
#> en18 Ecologia Numérica - Lecture 18: GLMs, links, and model selection
#> en19 Ecologia Numérica - Lecture 19: Generalized additive models
#> en20 Ecologia Numérica - Lecture 20: Correlation and contingency tables
#> en21 Ecologia Numérica - Lecture 21: Log-linear models and maximum likelihood
#> en22 Ecologia Numérica - Lecture 22: Multivariate data and classification
#> en23 Ecologia Numérica - Lecture 23: Distances and hierarchical clustering
#> en24 Ecologia Numérica - Lecture 24: Non-hierarchical clustering and ordination
#> en01 Ecologia Numérica - Class 01
#> en25 Ecologia Numérica - Lecture 25: PCA and other ordination methods
#> en02 Ecologia Numérica - Lecture 02: Critical thinking and observation filters
#> en03 Ecologia Numérica - Lecture 03: Scientific questions and falsifiable hypotheses
#> en04 Ecologia Numérica - Lecture 04: Variable types and probability rules
#> en05 Ecologia Numérica - Lecture 05: Random variables and distributions
#> en06 Ecologia Numérica - Lecture 06: Distribution functions in R
#> en07 Ecologia Numérica - Lecture 07: Sampling and stratification
#> title
#> console The Console Door
#> vector The Vector Cabinet
#> finddata Finding Data
#> datatab The Data Table Hatch
#> columns The Column Scanner
#> missing The Missing Value Mirror
#> plotwin The Plotting Window
#> habitat The Habitat Mosaic
#> hidden The Hidden Data
#> subset The Subsetting Lock
#> sorting The Sorting Staircase
#> model The Model Room
#> resid The Residual Drawer
#> predict The Prediction Lantern
#> detectp The Observation Filter
#> detect The Detection Counter
#> trunc The Truncation Gate
#> comment The Comment Cipher
#> webglm The Web Data Model
#> quarto The Quarto Exit
#> en08 The Aquarium Illusion
#> en09 The Standardisation Mirror
#> en10 The Sign Test Lock
#> en11 The Reference Growth Chamber
#> en12 The Ranked Shells
#> en13 The Three Meadows
#> en14 The Interaction Trap
#> en15 The Blocked Greenhouse
#> en16 The Regression Staircase
#> en17 The Residual Window
#> en18 The Logistic Gate
#> en19 The Curved Forest
#> en20 The Independence Table
#> en21 The Likelihood Nest
#> en22 The Community Matrix
#> en23 The Shared Species Lock
#> en24 The Two Shoals
#> en01 The First Practical Class
#> en25 The Final Principal Door
#> en02 The Invisible Birds
#> en03 The River Hypothesis
#> en04 The Two Habitat Gates
#> en05 The Nest Lottery
#> en06 The Temperature Vault
#> en07 The Unequal Habitats
#> learning_goal
#> console Use R as a calculator and learn expression order.
#> vector Create vectors and summarize them with functions.
#> finddata Find and inspect built-in R datasets.
#> datatab Read and inspect a CSV data set.
#> columns Identify variables in a data frame.
#> missing Check data quality before analysis.
#> plotwin Make a basic plot and read a visual pattern.
#> habitat Use tables to summarize categorical variables before plotting.
#> hidden Discover that plotted data can reveal structure hidden in plain text.
#> subset Subset data frames using logical conditions.
#> sorting Order data and inspect extreme observations.
#> model Fit and interpret a simple linear model.
#> resid Understand that fitted models leave residual variation.
#> predict Use a fitted model to predict for a new ecological setting.
#> detectp Connect observed data to an imperfect observation process.
#> detect Summarize detections as observed outcomes.
#> trunc Think about distance cutoffs and retained observations.
#> comment Recognize comments as part of readable R code.
#> webglm Read data from a web link and fit a Poisson GLM.
#> quarto Recognize reproducible reports as part of the analysis workflow.
#> en08 Identify experimental units and avoid counting subsamples as treatment replicates.
#> en09 Centre and scale measurements using the sample standard deviation.
#> en10 Calculate an exact two-sided binomial p-value under a stated null hypothesis.
#> en11 Compute a one-sample t statistic while recognizing independence and Normality assumptions.
#> en12 Calculate the positive-rank sum in a one-sample Wilcoxon signed-rank test.
#> en13 Fit a one-way ANOVA and extract the between-group F statistic.
#> en14 Recognize a factorial interaction through a difference of treatment effects.
#> en15 Account for matched blocks by analysing differences within each block.
#> en16 Fit a linear regression and interpret its slope in ecological units.
#> en17 Calculate residuals from a fitted model and identify the largest absolute residual.
#> en18 Transform a binomial GLM linear predictor into a probability on the response scale.
#> en19 Recognize when a smooth ecological response calls for a GAM.
#> en20 Compute an expected contingency-table count under independence.
#> en21 Find a Bernoulli maximum-likelihood estimate using a grid search.
#> en22 Organize sites as rows and species as columns, then summarize each species.
#> en23 Calculate Jaccard dissimilarity for presence-absence data while excluding joint absences.
#> en24 Run k-means with explicit initial centres and interpret a centre independently of its label.
#> en01 Use R arithmetic, square roots, and unit conversion to calculate travel time.
#> en25 Fit a PCA and calculate the proportion of variance explained by its first component.
#> en02 Distinguish observed counts from abundance when detection is imperfect.
#> en03 Translate a falsifiable ecological hypothesis into a numerical prediction.
#> en04 Calculate the probability of a union without double-counting an intersection.
#> en05 Calculate a binomial probability and recognize its assumptions.
#> en06 Use a cumulative distribution function to calculate an upper-tail probability.
#> en07 Weight stratum means by the sizes of the strata.The id column is useful when building a shorter custom
quest, where you can provide a list of rooms to be played as a separate
quest. See next section and the corresponding dedicated vignette for
details on how to create new rooms and quests.
Instructors can build a quest from selected room IDs, as an example here, a mini 3-room quest:
short_quest <- build_escape(c("console", "vector", "plotwin"))
escape(player = "demo_short", reset = TRUE, escape = short_quest)The same escape() command starts the custom sequence.
The only difference is that the escape argument receives an
escape sequence created with build_escape().
list_escapes() shows all named sequences, including the
built-in foundations sequence and sequences supplied by
registered room packs:
list_escapes()
#> id pack_id
#> foundations builtin
#> en2026 en2026 enpack
#> enintro enintro enpack
#> rooms
#> console, vector, finddata, datatab, columns, missing, plotwin, habitat, hidden, subset, sorting, model, resid, predict, detectp, detect, trunc, comment, webglm, quarto
#> en2026 en01, en02, en03, en04, en05, en06, en07, en08, en09, en10, en11, en12, en13, en14, en15, en16, en17, en18, en19, en20, en21, en22, en23, en24, en25
#> enintro en01Those named sequences can also be passed to
build_escape(). For a new or reset game, omitting the
sequence selects foundations, so these two calls select the
same rooms:
Here is the core command set while playing:
escape() # start or resume a quest
play() # show the current room again
hint() # request the next hint
submit(70) # submit an answer
status() # check progress
reset_game() # restart the active quest
list_rooms() # inspect available roomsThe most important habit is to solve the room in ordinary R first. The game is the lock; R is the key. Can you get out?
Remove a saved profile with delete_progress("ana") when
it is no longer needed. delete_progress() removes the
active profile and closes that game. Set
options(escapeR.progress_dir = "path") to select a
different directory. For demonstrations, use temporary storage and clean
it up afterwards. Profiles are case-insensitive; punctuation is replaced
by underscores in filenames. Names that map to another player’s saved
file are rejected. An unreadable save can be removed or deliberately
restarted with escape(player, reset = TRUE).