Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ Suggests:
testthat (>= 3.0.0),
digest
Remotes:
rstudio/learnr,
rstudio/gradethis
29 changes: 25 additions & 4 deletions R/build_learnr.R
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ build_learnr <- function(template_file_path, packages = c("learnr", "gradethis",
packages <- c(packages, template$packages)
}

setup <- paste("```{r setup, include=FALSE}\n", paste("library(", packages, ")", sep = "", collapse = "\n"), "\n```\n")
setup <- paste(
"```{r setup, include=FALSE}\n",
paste("library(", packages, ")", sep = "", collapse = "\n"),
"\n",
ifelse("setup" %in% names(template), template$setup, ""),
"\n```\n")

intro <- template$introduction

Expand Down Expand Up @@ -176,7 +181,8 @@ build_content <- function(content, depth = 1, section = 0) {
} else if (item$type == "section") {
markdownText <- paste0(markdownText, prefix, " ", item$title, "\n\n", build_content(item$content, depth + 1))
} else if (item$type == "image") {
markdownText <- paste0(markdownText, "![", item$alt, "](", item$src, ")\n\n")
markdownText <- paste0(markdownText, "<img src='", item$src, "' alt='", item$alt, "' style='max-width: 100%;' />\n\n")
#markdownText <- paste0(markdownText, "![", item$alt, "](", item$src, ")\n\n")
} else if (item$type == "code") {
if(is.null(item$name)) {
item$name <- paste0("ex-", generateCodeBlockName(item))
Expand Down Expand Up @@ -204,7 +210,7 @@ build_content <- function(content, depth = 1, section = 0) {
} else if (item$type == "table") {
# Simple table conversion; consider enhancing for complex tables
headerRow <- paste("|", paste(item$header, collapse = " | "), "|")
separatorRow <- paste("|", paste(rep("---", length(item$header)), collapse = " | "), "|")
separatorRow <- paste("|", paste(rep(":---", length(item$header)), collapse = " | "), "|")
bodyRows <- sapply(item$rows, function(row) paste("|", paste(row, collapse = " | "), "|"))
tableMarkdown <- paste(c(headerRow, separatorRow, bodyRows), collapse = "\n")
markdownText <- paste0(markdownText, tableMarkdown, "\n\n")
Expand Down Expand Up @@ -271,6 +277,7 @@ build_exercise <- function(exercise, exercise_number) {
hints <- exercise$hints
solution <- exercise$solution$code
explanation <- exercise$solution$explanation
custom_check <- exercise$solution$check

# Initialize the Rmarkdown content with the exercise instruction
rmarkdown_content <- paste0("### Exercise ", exercise_number, "\n\n", instructions, "\n\n```{r exercise", exercise_number, ", exercise = TRUE}\n# Your code here\n```\n\n")
Expand All @@ -288,7 +295,21 @@ build_exercise <- function(exercise, exercise_number) {
explanation_formatted <- stringr::str_replace_all(explanation, "\n", " ")

# Add the exercise check to the Rmarkdown content
rmarkdown_content <- paste0(rmarkdown_content, "```{r exercise", exercise_number, "-check}\ngrade_this_code(\n correct = c(gradethis::random_praise(), \"", explanation_formatted, "\")\n)\n```\n")
if (!is.null(custom_check)) {
rmarkdown_content <- paste0(
rmarkdown_content,
"```{r exercise", exercise_number, "-check}\n",
custom_check,
"\n```\n"
)
} else {
rmarkdown_content <- paste0(
rmarkdown_content,
"```{r exercise", exercise_number, "-check}\ngrade_this_code(\n correct = c(gradethis::random_praise(), \"",
explanation_formatted,
"\")\n)\n```\n"
)
}

return(rmarkdown_content)

Expand Down
78 changes: 78 additions & 0 deletions R/reset_lessons.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#' Reset a specified lesson from the available tutorials
#'
#' This function allows the user to reset a specific lesson from the available tutorials in the `trainingRIntro` package.
#' It prompts the user to select a lesson if not specified. It checks the validity of the input and handles errors
#' appropriately, ensuring that only available lessons can be reset.
#'
#' @param number An optional integer specifying the lesson number to reset.
#' If NA (default), the function will prompt the user to choose a lesson.
#'
#' @details If `number` is not provided or is NA, the function prompts the user interactively to choose a lesson from
#' a list of available tutorials. The function ensures that the input corresponds to a valid lesson number
#' and provides error feedback for invalid entries.
#'
#' @return NULL, the function is used for its side effects of running a lesson interactively.
#' @importFrom learnr available_tutorials
#' @importFrom learnr run_tutorial
#' @export
reset_lesson <- function(number = NA) {

x <- learnr::available_tutorials()
x <- x[x$package == "trainingRIntro", ]

if(nrow(x) == 0) {
stop("No lessons found")
}

# If number is NA (not provided), prompt user to choose a lesson
if(is.na(number)) {
cat("Please choose a lesson to reset by entering its number:\n")
for(i in 1:nrow(x)) {
cat(i, ": ", x$title[i], "\n", sep = "")
}

# Using readline() to get input from user
repeat {
number <- as.integer(readline(prompt = "Enter the lesson number: "))
if(!is.na(number) && number > 0 && number <= nrow(x)) break
cat("Invalid input. Please enter a number between 1 and ", nrow(x), ".\n", sep = "")
}
}

user <- Sys.info()['user']

dir <- paste0("training.r.intro.", number)

storage_path <- file.path(rappdirs::user_data_dir(), "R", "learnr", "tutorial", "storage", user, dir)

if (dir.exists(storage_path)) {
dir.remove(storage_path, recursive = TRUE)
}

}

#' Resets the user's progress in the trainingRIntro package
#'
#' This function allows the user to reset all lessons from the available tutorials in the `trainingRIntro` package.
#'
#' @export
reset_training <- function() {

x <- learnr::available_tutorials()
x <- x[x$package == "trainingRIntro", ]

if(nrow(x) == 0) {
stop("No lessons found")
}

for(i in 1:nrow(x)) {
reset_lesson(i)
}

if(file.exists(user_state_file())) {
file.remove(user_state_file())
}

return(invisible(TRUE))

}
22 changes: 11 additions & 11 deletions docs/1-Introduction/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@ Once you have installed R, you can open the program itself. On a PC, if you have
will look like this:


![R icon](./images/r_icon.png)
<img src='./images/r_icon.png' alt='R icon' style='max-width: 100%;' />

Once opened, the R console looks very plain.


![R console](./images/r_console.png)
<img src='./images/r_console.png' alt='R console' style='max-width: 100%;' />

RStudio makes R much more user friendly. It's free and can be downloaded from the [Posit website](https://posit.co/download/rstudio-desktop/).
Accept the defaults during installation. It's not necessary to open RStudio to use R, but in these sessions we will assume that RStudio is your
Expand All @@ -95,29 +95,29 @@ interface to R.
On a PC, the RStudio desktop icon looks like this:


![RStudio icon](./images/rstudio_icon.png)
<img src='./images/rstudio_icon.png' alt='RStudio icon' style='max-width: 100%;' />

When you first open RStudio, this is what you see:


![RStudio interface](./images/rstudio_interface.png)
<img src='./images/rstudio_interface.png' alt='RStudio interface' style='max-width: 100%;' />

The left panel is the console for R. Type `1 + 1` in the console then hit "Enter" and R will return the answer.


![RStudio console with calculation](./images/rstudio_calculation.png)
<img src='./images/rstudio_calculation.png' alt='RStudio console with calculation' style='max-width: 100%;' />

It's a good idea to use a script so you can save your code. Open a new script by selecting "File" -> "New File" -> "R Script" and it will appear
in the top left panel of RStudio.


![New R script in RStudio](./images/rstudio_new_script.png)
<img src='./images/rstudio_new_script.png' alt='New R script in RStudio' style='max-width: 100%;' />

This is a text document that can be saved. Go to "File" -> "Save As" and you can save the file with a `.R` extension. You can type and run more
than one line at a time by highlighting and clicking the "Run" button on the script tool bar.


![Running a script in RStudio](./images/rstudio_run_script.png)
<img src='./images/rstudio_run_script.png' alt='Running a script in RStudio' style='max-width: 100%;' />

The bottom right panel can be used to find and open files, view plots, load packages, and look at help pages. The top right panel gives you information
about what variables you're working with during your R session.
Expand All @@ -143,7 +143,7 @@ in the R language.


| Operator | Meaning | Example |
| --- | --- | --- |
| :--- | :--- | :--- |
| + | addition | 2 + 2 |
| - | subtraction | 2 - 2 |
| * | multiplication | 2 * 2 |
Expand Down Expand Up @@ -221,7 +221,7 @@ x + y
In RStudio, you will see the variables we created in the top right panel.


![Variables in RStudio](./images/rstudio_variables.png)
<img src='./images/rstudio_variables.png' alt='Variables in RStudio' style='max-width: 100%;' />

If you've already created a variable, you can replace the value with another value.

Expand All @@ -240,7 +240,7 @@ x
In the top right panel you can see that the number stored in the variable `x` has changed.


![Updated variable in RStudio](./images/rstudio_updated_variable.png)
<img src='./images/rstudio_updated_variable.png' alt='Updated variable in RStudio' style='max-width: 100%;' />

There are 3 important rules to remember when creating variable names:

Expand All @@ -264,7 +264,7 @@ R has three main data types:


| Type | Description | Examples |
| --- | --- | --- |
| :--- | :--- | :--- |
| character | letters and words | `z`, `red`, `H2O` |
| numeric | numbers | `1`, `3.14`, `log(10)` |
| logical | binary | `TRUE`, `FALSE` |
Expand Down
15 changes: 11 additions & 4 deletions docs/2-Functions-and-Importing-Data/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Many functions also have additional options you can choose, which are called the
In RStudio, you will see the help page for `mean()` in the bottom right corner panel.


![RStudio help page for the mean function](images/rstudio_help.png)
<img src='images/rstudio_help.png' alt='RStudio help page for the mean function' style='max-width: 100%;' />

On the help page, under `Usage`, you see `mean(x, ...)`. This means that the only thing that necessarily has to go into `( )` is `x`. On the help page under `Arguments` you will find a description of what `x` needs to be: a numeric or logical vector.

Expand Down Expand Up @@ -301,12 +301,12 @@ It's not available because we need to install the package first (again, like ini
In the bottom right panel of RStudio, click on the "Packages" tab then click "Install Packages" in the tool bar.


![RStudio Install Packages tab](images/rstudio_install_package.png)
<img src='images/rstudio_install_package.png' alt='RStudio Install Packages tab' style='max-width: 100%;' />

A window will pop up. Start typing "EnvStats" into the "Packages" box, select that package, and click "Install".


![RStudio package installation window for EnvStats](images/rstudio_install_package2.png)
<img src='images/rstudio_install_package2.png' alt='RStudio package installation window for EnvStats' style='max-width: 100%;' />

Now that we've installed the package, we still can't use the function we want. We need to load the package first (opening the app). We use the `library()` function to do this.

Expand Down Expand Up @@ -377,7 +377,14 @@ library(readxl)
Use the `read_excel()` function from the `readxl` package to read emissions data from [this Excel workbook](https://github.com/LADCO/training-r-intro/blob/main/data/emissions_IL_2022.xlsx). Download the file to your working directory and read the first worksheet (named "UNIT_DATA"), skipping the first 6 rows.


```{r ex-42c0a66e0643, exercise = TRUE, exercise.eval = FALSE, exercise.lines = 5, exercise.cap = 'Read and Inspect Excel Data'}
```{r ex-4cbff1905b04, exercise = FALSE, eval = FALSE, exercise.cap = 'Read and Inspect Excel Data'}
library(readxl)
emissions <- read_excel("emissions_IL_2022.xlsx", sheet = "UNIT_DATA", skip = 6)
head(emissions)

```

```{r ex-42c0a66e0643, echo = FALSE, eval = TRUE, exercise.cap = 'Read and Inspect Excel Data'}
library(readxl)
emissions <- read_excel("./data/emissions_IL_2022.xlsx", sheet = "UNIT_DATA", skip = 6)
head(emissions)
Expand Down
2 changes: 1 addition & 1 deletion docs/3-Subsetting-Sorting-and-Combining/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ View(chicago_air)

```

![View function output in RStudio](images/view.png)
<img src='images/view.png' alt='View function output in RStudio' style='max-width: 100%;' />

By inspecting the data frame this way, you can see that the records are daily values of ozone, temperature, and air pressure. For more information about the data set you can type a question mark in from the name of the data frame variable in the console.

Expand Down
6 changes: 3 additions & 3 deletions docs/4-Writing-Functions-Conditionals-and-Loops/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ This lesson assumes you are familiar with the material in the previous lessons:
- Functions and Importing Data
- Subsetting, Sorting, and Combining Data Frames

The data for these lessons is available from this package. It is assumed that this package is already installed and loaded into the R session. If you need to refer to the package, simply refer to it as "this package".
The data for these lessons is available from this package or the `region5air` package.


```{r ex-b0dd7d25d817, exercise = FALSE, exercise.eval = TRUE, exercise.cap = 'Load Data from This Package'}
```{r ex-868d2c8c5b75, exercise = FALSE, exercise.eval = TRUE, exercise.cap = 'Load Data from the Package'}
# Assuming the package is already loaded

data(chicago_air)
Expand Down Expand Up @@ -61,7 +61,7 @@ We can write a simple function that prints something to the console. Here is a
function named `print_hello`.


```{r ex-a3bc32a64175, exercise = TRUE, exercise.eval = TRUE, exercise.cap = 'Simple Function to Print Hello'}
```{r ex-a3bc32a64175, exercise = TRUE, exercise.eval = TRUE, eval = TRUE, exercise.cap = 'Simple Function to Print Hello'}
print_hello <- function() {

print("Hello")
Expand Down
2 changes: 1 addition & 1 deletion docs/5-Plotting/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ Plots can be saved in RStudio using the "Export" button at the top of the "Plots
pane.


![Screenshot showing how to save plots in RStudio.](./images/save_plot.png)
<img src='./images/save_plot.png' alt='Screenshot showing how to save plots in RStudio.' style='max-width: 100%;' />

You can also save a plot made by `ggplot2` using the `ggsave()` function.

Expand Down
2 changes: 1 addition & 1 deletion docs/6-Basic-Statistics/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ Below is a reference table of a few popular tests for categorical data analysis


| test | function |
| --- | --- |
| :--- | :--- |
| Chi Square Test | `chisq.test()` |
| Fisher's Test | `fisher.test()` |
| Analysis of Variance | `aov()` |
Expand Down
Loading