From e96782c9d750ec689418ccbafa9fd29c7860ab5c Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Sun, 5 May 2024 16:39:12 -0400 Subject: [PATCH 1/7] fixes for images, tables, and lessons (minus exercises) --- R/build_learnr.R | 5 +- docs/1-Introduction/readme.md | 24 ++--- docs/2-Functions-and-Importing-Data/readme.md | 19 ++-- .../readme.md | 4 +- .../readme.md | 4 +- docs/5-Plotting/readme.md | 6 +- docs/6-Basic-Statistics/readme.md | 2 +- inst/tutorials/1-Introduction/lesson.Rmd | 11 +- inst/tutorials/1-Introduction/lesson.html | 100 ++++-------------- .../2-Functions-and-Importing-Data/lesson.Rmd | 22 ++-- .../lesson.Rmd | 4 +- .../lesson.Rmd | 4 +- inst/tutorials/5-Plotting/lesson.Rmd | 6 +- inst/tutorials/6-Basic-Statistics/lesson.Rmd | 2 +- .../lesson2.yaml | 17 ++- .../lesson4.yaml | 4 +- 16 files changed, 97 insertions(+), 137 deletions(-) diff --git a/R/build_learnr.R b/R/build_learnr.R index c7f1d46..8f038eb 100644 --- a/R/build_learnr.R +++ b/R/build_learnr.R @@ -176,7 +176,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, "", item$alt, "\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)) @@ -204,7 +205,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") diff --git a/docs/1-Introduction/readme.md b/docs/1-Introduction/readme.md index 2457838..a790df8 100644 --- a/docs/1-Introduction/readme.md +++ b/docs/1-Introduction/readme.md @@ -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) +R icon Once opened, the R console looks very plain. -![R console](./images/r_console.png) +R console 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 @@ -95,29 +95,29 @@ interface to R. On a PC, the RStudio desktop icon looks like this: -![RStudio icon](./images/rstudio_icon.png) +RStudio icon When you first open RStudio, this is what you see: -![RStudio interface](./images/rstudio_interface.png) +RStudio interface 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) +RStudio console with calculation 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) +New R script in RStudio 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) +Running a script in RStudio 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. @@ -125,7 +125,7 @@ about what variables you're working with during your R session. ## Basic Math -Open up a script if you haven't already (File -> New File -> R Script). Try some math by either typing the lines below or copying and pasting +Open up a script if you haven't already (“File” -> “New File” -> “R Script”). Try some math by either typing the lines below or copying and pasting the lines into your script. @@ -143,7 +143,7 @@ in the R language. | Operator | Meaning | Example | -| --- | --- | --- | +|: --- | --- | --- | | + | addition | 2 + 2 | | - | subtraction | 2 - 2 | | * | multiplication | 2 * 2 | @@ -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) +Variables in RStudio If you've already created a variable, you can replace the value with another value. @@ -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) +Updated variable in RStudio There are 3 important rules to remember when creating variable names: @@ -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` | diff --git a/docs/2-Functions-and-Importing-Data/readme.md b/docs/2-Functions-and-Importing-Data/readme.md index d4192f7..5c1fcad 100644 --- a/docs/2-Functions-and-Importing-Data/readme.md +++ b/docs/2-Functions-and-Importing-Data/readme.md @@ -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) +RStudio help page for the mean function 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. @@ -239,7 +239,7 @@ mean(seq(from=1, to=10, by=3)) ``` -_Note: Typically you dont want to have too many nested functions because it becomes difficult to read._ +_Note: Typically you don’t want to have too many nested functions because it becomes difficult to read._ ## NA Values @@ -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) +RStudio Install Packages tab 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) +RStudio package installation window for EnvStats 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. @@ -322,7 +322,7 @@ serialCorrelationTest(x) Here is a link to a page that lists many useful packages for environmental data analysis: https://cran.r-project.org/web/views/Environmetrics.html -Remember, when you close down RStudio, then start it up again, you dont have to download the package again. But you do have to use the `library()` function to load the package before you can use any function that's not in the R core functionality (this is very easy to forget). +Remember, when you close down RStudio, then start it up again, you don’t have to download the package again. But you do have to use the `library()` function to load the package before you can use any function that's not in the R core functionality (this is very easy to forget). ## Importing Data @@ -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) diff --git a/docs/3-Subsetting-Sorting-and-Combining/readme.md b/docs/3-Subsetting-Sorting-and-Combining/readme.md index 0e5dafe..d83792b 100644 --- a/docs/3-Subsetting-Sorting-and-Combining/readme.md +++ b/docs/3-Subsetting-Sorting-and-Combining/readme.md @@ -99,7 +99,7 @@ View(chicago_air) ``` -![View function output in RStudio](images/view.png) +View function output in RStudio 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. @@ -161,7 +161,7 @@ my_data[3, 2] ``` -We can also access data from a vector using the same indexing idea. In this case, you dont need the comma to separate the rows and columns since you are accessing one dimensional data. Below is a vector of numbers. +We can also access data from a vector using the same indexing idea. In this case, you don’t need the comma to separate the rows and columns since you are accessing one dimensional data. Below is a vector of numbers. ```{r ex-81d6c088db05, exercise = FALSE, exercise.eval = TRUE, exercise.cap = 'Vector Indexing Example'} diff --git a/docs/4-Writing-Functions-Conditionals-and-Loops/readme.md b/docs/4-Writing-Functions-Conditionals-and-Loops/readme.md index b65c65a..3008b4f 100644 --- a/docs/4-Writing-Functions-Conditionals-and-Loops/readme.md +++ b/docs/4-Writing-Functions-Conditionals-and-Loops/readme.md @@ -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) diff --git a/docs/5-Plotting/readme.md b/docs/5-Plotting/readme.md index a447fd1..24fe85b 100644 --- a/docs/5-Plotting/readme.md +++ b/docs/5-Plotting/readme.md @@ -223,7 +223,7 @@ Additional modifications can be made. Customize it by adding color, title, and l ggplot(chicago_air, aes(x = temp, y = ozone)) + geom_point(color = "forestgreen") + ggtitle('Relationship between Ozone and Temperature') + - xlab('Temperature (F)') + + xlab('Temperature (°F)') + ylab('Ozone (ppm)') ``` @@ -238,7 +238,7 @@ argument `color` in the `aes( )` function. ggplot(chicago_air, aes(x = temp, y = ozone, color = factor(month))) + geom_point() + ggtitle('Relationship between Ozone and Temperature') + - xlab('Temperature (F)') + + xlab('Temperature (°F)') + ylab('Ozone (ppm)') ``` @@ -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) +Screenshot showing how to save plots in RStudio. You can also save a plot made by `ggplot2` using the `ggsave()` function. diff --git a/docs/6-Basic-Statistics/readme.md b/docs/6-Basic-Statistics/readme.md index e8757ca..1afcbb2 100644 --- a/docs/6-Basic-Statistics/readme.md +++ b/docs/6-Basic-Statistics/readme.md @@ -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()` | diff --git a/inst/tutorials/1-Introduction/lesson.Rmd b/inst/tutorials/1-Introduction/lesson.Rmd index dd3130e..e9b363a 100644 --- a/inst/tutorials/1-Introduction/lesson.Rmd +++ b/inst/tutorials/1-Introduction/lesson.Rmd @@ -14,6 +14,7 @@ output: runtime: shiny_prerendered --- + ```{r setup, include=FALSE} library(learnr) library(gradethis) @@ -64,7 +65,7 @@ a programming language. ## Basic Math -Open up a script if you haven't already (File -> New File -> R Script). Try some math by either typing the lines below or copying and pasting +Open up a script if you haven't already (“File” -> “New File” -> “R Script”). Try some math by either typing the lines below or copying and pasting the lines into your script. @@ -82,7 +83,7 @@ in the R language. | Operator | Meaning | Example | -| --- | --- | --- | +|: --- | --- | --- | | + | addition | 2 + 2 | | - | subtraction | 2 - 2 | | * | multiplication | 2 * 2 | @@ -160,7 +161,7 @@ x + y In RStudio, you will see the variables we created in the top right panel. -![Variables in RStudio](./images/rstudio_variables.png) +Variables in RStudio If you've already created a variable, you can replace the value with another value. @@ -179,7 +180,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) +Updated variable in RStudio There are 3 important rules to remember when creating variable names: @@ -203,7 +204,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` | diff --git a/inst/tutorials/1-Introduction/lesson.html b/inst/tutorials/1-Introduction/lesson.html index acfcad0..73594a9 100644 --- a/inst/tutorials/1-Introduction/lesson.html +++ b/inst/tutorials/1-Introduction/lesson.html @@ -10,11 +10,11 @@ - + - + 1 . Introduction to R @@ -164,11 +164,9 @@

Why Use a Programming Language?

Basic Math

-

Open up a script if you haven’t already -(<U+201C>File<U+201D> -> <U+201C>New -File<U+201D> -> <U+201C>R Script<U+201D>). Try some -math by either typing the lines below or copying and pasting the lines -into your script.

+

Open up a script if you haven’t already (“File” -> “New File” +-> “R Script”). Try some math by either typing the lines below or +copying and pasting the lines into your script.

10 + 5
## [1] 15
10 - 5
@@ -182,42 +180,10 @@

Basic Math

Remember, to run the lines, highlight your code and click the “Run” button on the toolbar of the script panel. Below is a table of the math operators in the R language.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OperatorMeaningExample
+addition2 + 2
-subtraction2 - 2
*multiplication2 * 2
/division2 / 2
^exponentiation2 ^ 2
+
Operator | Meaning | Example |
+

|: — | — | — | | + | addition | 2 + 2 | | - | subtraction | 2 - 2 | | +* | multiplication | 2 * 2 | | / | division | 2 / 2 | | ^ | +exponentiation | 2 ^ 2 |

Order of Operations

R follows the usual order of arithmetical operations and uses @@ -277,10 +243,7 @@

Variables

## [1] 15

In RStudio, you will see the variables we created in the top right panel.

-
-Variables in RStudio -
Variables in RStudio
-
+

Variables in RStudio

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

x
@@ -294,11 +257,7 @@

Variables

In the top right panel you can see that the number stored in the variable x has changed.

-
- -
Updated variable in RStudio
-
+

Updated variable in RStudio

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

    @@ -317,32 +276,11 @@

    Variables

    Data Types

    R has three main data types:

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeDescriptionExamples
    characterletters and wordsz, red, H2O
    numericnumbers1, 3.14, log(10)
    logicalbinaryTRUE, FALSE
    +
    Type | Description | Examples |
    +

    |: — | — | — | | character | letters and words | z, +red, H2O | | numeric | numbers | +1, 3.14, log(10) | | logical | +binary | TRUE, FALSE |

    The character type requires single or double quotes. The numeric type must be unquoted numbers, and the full-caps logical values TRUE and FALSE must also be unquoted.

    @@ -1215,12 +1153,12 @@

    Next Lesson

    @@ -1237,7 +1175,7 @@

    Next Lesson

    1 . Introduction to R

    Fluent Data, LLC

    -

    2024-05-02

    +

    2024-05-05

diff --git a/inst/tutorials/2-Functions-and-Importing-Data/lesson.Rmd b/inst/tutorials/2-Functions-and-Importing-Data/lesson.Rmd index 10b93cd..4019b4c 100644 --- a/inst/tutorials/2-Functions-and-Importing-Data/lesson.Rmd +++ b/inst/tutorials/2-Functions-and-Importing-Data/lesson.Rmd @@ -17,8 +17,7 @@ runtime: shiny_prerendered library(learnr) library(gradethis) library(trainingRIntro) -library(shiny) -library(EnvStats) +library(shiny) ``` This lesson covers the use of functions in R, including built-in functions and functions from packages. It also discusses how to import @@ -83,7 +82,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) +RStudio help page for the mean function 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. @@ -233,7 +232,7 @@ mean(seq(from=1, to=10, by=3)) ``` -_Note: Typically you dont want to have too many nested functions because it becomes difficult to read._ +_Note: Typically you don’t want to have too many nested functions because it becomes difficult to read._ ## NA Values @@ -295,12 +294,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) +RStudio Install Packages tab 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) +RStudio package installation window for EnvStats 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. @@ -316,7 +315,7 @@ serialCorrelationTest(x) Here is a link to a page that lists many useful packages for environmental data analysis: https://cran.r-project.org/web/views/Environmetrics.html -Remember, when you close down RStudio, then start it up again, you dont have to download the package again. But you do have to use the `library()` function to load the package before you can use any function that's not in the R core functionality (this is very easy to forget). +Remember, when you close down RStudio, then start it up again, you don’t have to download the package again. But you do have to use the `library()` function to load the package before you can use any function that's not in the R core functionality (this is very easy to forget). ## Importing Data @@ -371,7 +370,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) diff --git a/inst/tutorials/3-Subsetting-Sorting-and-Combining/lesson.Rmd b/inst/tutorials/3-Subsetting-Sorting-and-Combining/lesson.Rmd index 70af565..89d2cf8 100644 --- a/inst/tutorials/3-Subsetting-Sorting-and-Combining/lesson.Rmd +++ b/inst/tutorials/3-Subsetting-Sorting-and-Combining/lesson.Rmd @@ -100,7 +100,7 @@ View(chicago_air) ``` -![View function output in RStudio](images/view.png) +View function output in RStudio 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. @@ -162,7 +162,7 @@ my_data[3, 2] ``` -We can also access data from a vector using the same indexing idea. In this case, you dont need the comma to separate the rows and columns since you are accessing one dimensional data. Below is a vector of numbers. +We can also access data from a vector using the same indexing idea. In this case, you don’t need the comma to separate the rows and columns since you are accessing one dimensional data. Below is a vector of numbers. ```{r ex-81d6c088db05, exercise = FALSE, exercise.eval = TRUE, exercise.cap = 'Vector Indexing Example'} diff --git a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd index b92dbe7..9d93b8b 100644 --- a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd +++ b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd @@ -30,10 +30,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) diff --git a/inst/tutorials/5-Plotting/lesson.Rmd b/inst/tutorials/5-Plotting/lesson.Rmd index 0ac6952..304752b 100644 --- a/inst/tutorials/5-Plotting/lesson.Rmd +++ b/inst/tutorials/5-Plotting/lesson.Rmd @@ -223,7 +223,7 @@ Additional modifications can be made. Customize it by adding color, title, and l ggplot(chicago_air, aes(x = temp, y = ozone)) + geom_point(color = "forestgreen") + ggtitle('Relationship between Ozone and Temperature') + - xlab('Temperature (F)') + + xlab('Temperature (°F)') + ylab('Ozone (ppm)') ``` @@ -238,7 +238,7 @@ argument `color` in the `aes( )` function. ggplot(chicago_air, aes(x = temp, y = ozone, color = factor(month))) + geom_point() + ggtitle('Relationship between Ozone and Temperature') + - xlab('Temperature (F)') + + xlab('Temperature (°F)') + ylab('Ozone (ppm)') ``` @@ -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) +Screenshot showing how to save plots in RStudio. You can also save a plot made by `ggplot2` using the `ggsave()` function. diff --git a/inst/tutorials/6-Basic-Statistics/lesson.Rmd b/inst/tutorials/6-Basic-Statistics/lesson.Rmd index d48ec5b..c05fb24 100644 --- a/inst/tutorials/6-Basic-Statistics/lesson.Rmd +++ b/inst/tutorials/6-Basic-Statistics/lesson.Rmd @@ -223,7 +223,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()` | diff --git a/source/2-Functions-and-Importing-Data/lesson2.yaml b/source/2-Functions-and-Importing-Data/lesson2.yaml index 4e5f6fb..8aaf6f1 100644 --- a/source/2-Functions-and-Importing-Data/lesson2.yaml +++ b/source/2-Functions-and-Importing-Data/lesson2.yaml @@ -13,8 +13,6 @@ lesson: closing: | Well done on mastering Functions and Importing Data! You've expanded your toolkit with new R functions and data import techniques. In the next lesson, Subsetting, Sorting, and Combining Data Frames, you'll explore advanced data manipulation strategies to refine and optimize your data analysis workflows. -packages: - - EnvStats introduction: | This lesson covers the use of functions in R, including built-in functions and functions from packages. It also discusses how to import data from CSV text files and Excel documents. @@ -489,9 +487,18 @@ content: - type: code language: r options: - exercise: true - exercise.eval: false - exercise.lines: 5 + exercise: false + eval: false + exercise.cap: "Read and Inspect Excel Data" + content: | + library(readxl) + emissions <- read_excel("emissions_IL_2022.xlsx", sheet = "UNIT_DATA", skip = 6) + head(emissions) + - type: code + language: r + options: + echo: false + eval: true exercise.cap: "Read and Inspect Excel Data" content: | library(readxl) diff --git a/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml b/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml index 35426a0..a87d09f 100644 --- a/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml +++ b/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml @@ -26,13 +26,13 @@ content: - 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. - type: code language: r options: exercise: false exercise.eval: true - exercise.cap: "Load Data from This Package" + exercise.cap: "Load Data from the Package" content: | # Assuming the package is already loaded From 05223904a30c19bf41e463720578361a225f5e02 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Sun, 5 May 2024 16:49:03 -0400 Subject: [PATCH 2/7] updates --- DESCRIPTION | 1 + .../lesson.Rmd | 2 +- .../lesson.html | 1689 +++++++++++++++++ .../lesson4.yaml | 1 + 4 files changed, 1692 insertions(+), 1 deletion(-) create mode 100644 inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.html diff --git a/DESCRIPTION b/DESCRIPTION index 67afeda..5b39b27 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -34,3 +34,4 @@ Suggests: digest Remotes: rstudio/gradethis + rstudio/learnr diff --git a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd index 9d93b8b..bd2f7be 100644 --- a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd +++ b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd @@ -63,7 +63,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") diff --git a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.html b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.html new file mode 100644 index 0000000..fe7a7fe --- /dev/null +++ b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.html @@ -0,0 +1,1689 @@ + + + + + + + + + + + + + + + + + + +4 . Writing Functions, Conditionals, and Loops + + + + + + + + + + + + + + + + + + + + + +Skip to Tutorial Content + + + +
+
+ +
+ +

This lesson covers how to write your own R functions. It also +explains how to automate your code using if() and +ifelse() functions, for loops, and the apply +function.

+
+

Prerequisites

+

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 or the +region5air package.

+
# Assuming the package is already loaded
+
+data(chicago_air)
+
+
+

Writing Functions

+

As discussed in the second lesson on +functions, R can execute a saved chunk of code by running the name +of a function, like mean(). The name mean is +saved like a variable name, but since the name refers to a function, the +thing that’s saved is not a data object but lines of R code.

+

To save your own function, use this construction:

+
my_function_name <- function() {
+
+  # lines of R code
+
+}
+

We can write a simple function that prints something to the console. +Here is a function named print_hello.

+
+
print_hello <- function() {
+
+  print("Hello")
+
+}
+ +
+
+
print_hello()
+ +
+
+
+

Arguments

+

Most of the functions we have used in these lessons have had at least +one argument inside of the parentheses. The print_hello() +function did not have any arguments, so we could run it without putting +anything inside (). We could modify the function to take an +argument that pastes some text to the printed message.

+

Here we recreate the same function, but this time we add an argument +text inside of the parentheses.

+
+
print_hello <- function(text) {
+
+  message <- paste("Hello", text)
+
+  print(message)
+
+}
+ +
+

Now there are two lines of code inside of the curly braces. The first +line uses the paste() function to concatenate two character +values. The first value will always be “Hello”. The second value will be +supplied by the user in the text argument.

+
+
print_hello(text = "everybody!")
+ +
+
+
+

Default Values

+

We can create a function with more than one argument, and set default +values when needed. Suppose we would like to make a function that checks +if a measurement is greater than a criteria pollutant standard. We could +make a simple function that takes two arguments: one for the measurement +value, and one for the standard value.

+
+
standard_violated <- function(measurement, standard) {
+
+  measurement > standard
+
+}
+ +
+

This function will simply return a TRUE or +FALSE value, depending on whether the measurement is +greater than the standard or not.

+
+
standard_violated(measurement = 84, standard = 70)
+ +
+

We could write a more specific function for checking a value against +the ozone standard. For this function, we want to keep the +standard parameter but make sure the default is +70. It may be that we typically want to use this function +to check against the current 8-hour ozone standard in parts per billion, +but have the flexibility to use a different value.

+

To set a default value, we use = 70 when we create the +function.

+
+
standard_violated <- function(measurement, standard = 70) {
+
+  measurement > standard
+
+}
+ +
+

Now, when we use the function, it is not necessary to set the +standard argument.

+
+
standard_violated(measurement = 50)
+ +
+
+
+

Positional Arguments

+

One final note on functions in R. When a function is created, the +order of the arguments are important. The user can supply values for the +arguments in the order they appeared in the parentheses of the +function( ){} call, without writing out the argument +names.

+

For example, we can supply two numbers to the +standard_violated() function that we created above, without +writing out the measurement and standard +arguments. When R executes the function, it will assign the numbers to +the arguments based on the position in the parentheses.

+

Here we show that using two numbers in a different order will return +different outputs.

+
+
standard_violated(60, 70)
+ +
+
+
standard_violated(70, 60)
+ +
+
+
+

if Functions

+

Writing custom functions is a good way to standardize some R code +that can be reused on different data sets. It’s also helpful to write +code that will execute different lines of code depending on different +scenarios. The functions if() and ifelse() +allow you to control what code is executed based on a logical +condition.

+

The if() function takes the logical condition in the +parentheses. The code that will run if the logical expression is +TRUE is placed inside curly braces. Below is the outline +(not actual R code).

+
if(<logical expression>) {
+
+  <code that will run if the logical expression is TRUE>
+
+}
+

The key word else can also be used with another set of +curly braces to hold code that will only run if the logical expression +returns FALSE.

+
if(<logical expression>) {
+
+  <code that will run if the logical expression is true>
+
+} else {
+
+  <code that will run if the logical expression is false>
+
+}
+

For example, if we wanted to print a message based on the value of +ozone, we could use this construction:

+
+
ozone <- 0.075
+
+if(ozone > 0.065) {
+
+  print("Potential Health Effects")
+
+} else {
+
+  print("All Good")
+
+}
+ +
+

Since the expression ozone > 0.065 resolves to +TRUE, the code in the first set of curly braces is run. If +we set the ozone variable to 0.06, then the +logical expression will resolve to FALSE and the code in +the second curly braces will run.

+
+
ozone <- 0.06
+
+if(ozone > 0.065) {
+
+  print("Potential Health Effects")
+
+} else {
+
+  print("All Good")
+
+}
+ +
+

The ifelse() function is another way to use a logical +condition that determines which output is returned. Here is the +outline

+
ifelse(<test>, <yes>, <no>)
+

The test argument is the logical expression, +yes is the value returned if the expression resolves to +TRUE, and no is the value returned if the +expression resolves to FALSE.

+

Here we accomplish the same task as the previous example. This time +we use the ifelse() function to create a variable named +message.

+
+
ozone_value <- 0.06
+
+message <- ifelse(ozone_value > 0.065, "Potential Health Effects", "All Good")
+
+print(message)
+ +
+
+
+

For loops

+

Like most programming languages, R has for and while loops. This +tutorial will cover just for loops and move on to apply() +functions, which are more commonly used in R.

+

For loops are used to repeat an operation a set number of times. Here +is the basic outline:

+
for(i in sequence){
+
+  <code that will run a set number of times>
+
+}
+

The sequence parameter is typically a vector. The +i parameter is a variable that will take on the values in +the sequence vector. For instance, if sequence +was the vector c(1, 2, 3) then the i variable +will take on each of those values in turn.

+

This example simply prints the values of the vector as the for loop +progresses.

+
+
for(i in c(1, 2, 3)) {
+
+  print(i)
+
+}
+ +
+

Typically when we use loops, we want to perform the same operation on +different sets of data and save the results. To do this using the +for() function in R, we need to create an empty vector (or +list or data frame) and save the results during each iteration.

+

Here is an example data frame we will use. It represents a few values +from three monitors.

+
+
monitors <- data.frame(monitor1 = c(50, 60, 58, 52),
+                       monitor2 = c(55, 59, 65, 61),
+                       monitor3 = c(70, 62, 68, 71))
+
+monitors
+ +
+

In the code below, we create an empty vector called max_values. As +the for() function loops through the vector c(1, 2, 3), the data frame +columns are accessed using square brackets [ , i]. Each max value is +saved to the max_values vector using square brackets [i].

+
+
max_values <- c()
+
+for(i in c(1, 2, 3)) {
+
+  max_values[i] <- max(monitors[, i])
+
+}
+
+max_values
+ +
+
+
+

apply function

+

Although the for loop is common in programming languages, it is not +the most efficient way to apply a function to different sets of data in +R. The most efficient way to do loops in R is with the +apply() family of functions, including +lapply(), tapply(), and mapply(). +This section will demonstrate how to use the apply() +function.

+

The apply() function takes a data frame (or matrix) as +the first argument. The second argument determines if each loop will +apply to the rows (1) or columns (2). And the +third argument is the function you want to apply to each row or column. +Additional arguments can be used to pass on to the function being +applied to each row or column.

+

The example below applies the max() function to the +monitors data frame from the previous section.

+
+
monitors_max <- apply(monitors, MARGIN = 2, FUN = max)
+
+monitors_max
+ +
+

The MARGIN argument is set to 2 because we are applying the max() +function to the columns of the data frame. Also notice that we do not +need to create an initial empty vector, as we did with the for() +function. The returned value is a named vector that is as long as the +number of columns in the data frame.

+

We could also find the mean of each row in the monitors +data frame. To do this, we would set the MARGIN argument to +1.

+
+
apply(monitors, MARGIN = 1, FUN = mean)
+ +
+
+
+

Exercises

+
+

Exercise 1

+

Write a function named ppm_to_ppb that converts a value +from parts per million to parts per billion.

+
+
# Your code here
+ +
+
+
# Define the function `ppm_to_ppb` with one argument for the value you want to convert.
+
+
+
# Inside the function, multiply the input value by 1000 to convert it to parts per billion.
+
+
+
# Return the converted value.
+
+
+
ppm_to_ppb <- function(value) {
+  value * 1000
+}
+
+
+
+

Exercise 2

+

Write a function named check_value that prints “warning” +if a value is above a threshold, and “OK” if it’s below. Make the +threshold an argument in the function.

+
+
# Your code here
+ +
+
+
# Define the function `check_value` with two arguments: `value` and `threshold`.
+
+
+
# Use an `if` statement to check if `value` is greater than `threshold`.
+
+
+
# Print "warning" if the value is above the threshold, otherwise print "OK".
+
+
+
check_value <- function(value, threshold) {
+  if(value > threshold) {
+    print("warning")
+  } else {
+    print("OK")
+  }
+}
+
+
+
+

Exercise 3

+

Use the for() function to loop through the +temp column of the data from this package and print any +value that is above 90 degrees.

+
+
# Your code here
+ +
+
+
# Access the `temp` column of the data frame within the loop.
+
+
+
# Use a `for` loop to iterate over each value in the `temp` column.
+
+
+
# Inside the loop, use an `if` statement to check if the current temperature value is greater than 90.
+
+
+
# If a value is above 90, use `print()` to display it.
+
+
+
for (i in chicago_air$temp) {
+  if(i > 90) {
+    print(i)
+  }
+}
+
+
+
+

Exercise 4

+

Use the apply() function to create a vector of the mean +values from the numeric columns in the data from this package.

+
+
# Your code here
+ +
+
+
# First, subset the data frame to include only the numeric columns you wish to analyze.
+
+
+
# Use the `apply()` function with the subsetted data frame, specifying `MARGIN = 2` to apply the function across columns.
+
+
+
# Use the `mean` function as the `FUN` argument, including `na.rm = TRUE` to handle missing values.
+
+
+
chicago_numeric <- chicago_air[, c("ozone", "temp", "pressure")]
+mean_values <- apply(chicago_numeric, MARGIN = 2, FUN = mean, na.rm = TRUE)
+mean_values
+
+
+
+
+

Next Lesson

+

You have completed Lesson . Click the button below to mark it as +complete and move on to the next lesson.

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + + +
+ +
+ +
+
+
+
+ + +
+

4 . Writing +Functions, Conditionals, and Loops

+

Fluent Data, LLC

+

2024-05-05

+
+ + +
+
+
+
+ + +
+
+ + + + + + + + + + + + + + + + diff --git a/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml b/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml index a87d09f..f2ee345 100644 --- a/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml +++ b/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml @@ -69,6 +69,7 @@ content: options: exercise: true exercise.eval: true + eval: true exercise.cap: "Simple Function to Print Hello" content: | print_hello <- function() { From 1c4b66440a5a08f6eb7cd772b85b04e96e48aeb1 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Sun, 5 May 2024 16:49:55 -0400 Subject: [PATCH 3/7] oops --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5b39b27..a242c10 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -33,5 +33,5 @@ Suggests: testthat (>= 3.0.0), digest Remotes: - rstudio/gradethis + rstudio/gradethis, rstudio/learnr From bb78e39b23b93fd929e1a4ed046a4afc1e818c74 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Sun, 5 May 2024 16:51:21 -0400 Subject: [PATCH 4/7] hmm --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index a242c10..b668b44 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -33,5 +33,5 @@ Suggests: testthat (>= 3.0.0), digest Remotes: - rstudio/gradethis, - rstudio/learnr + rstudio/learnr, + rstudio/gradethis From 0746573db9b1243482eeb11d0b6477348993e75a Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Sun, 5 May 2024 17:02:37 -0400 Subject: [PATCH 5/7] testing setup updates --- R/build_learnr.R | 7 +- .../readme.md | 2 +- inst/tutorials/1-Introduction/lesson.Rmd | 1 + .../2-Functions-and-Importing-Data/lesson.Rmd | 1 + .../lesson.Rmd | 1 + .../lesson.Rmd | 6 + .../lesson.html | 1689 ----------------- inst/tutorials/5-Plotting/lesson.Rmd | 1 + inst/tutorials/6-Basic-Statistics/lesson.Rmd | 1 + inst/tutorials/7-Quality-Assurance/lesson.Rmd | 1 + .../lesson4.yaml | 5 + 11 files changed, 24 insertions(+), 1691 deletions(-) delete mode 100644 inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.html diff --git a/R/build_learnr.R b/R/build_learnr.R index 8f038eb..33ad945 100644 --- a/R/build_learnr.R +++ b/R/build_learnr.R @@ -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 diff --git a/docs/4-Writing-Functions-Conditionals-and-Loops/readme.md b/docs/4-Writing-Functions-Conditionals-and-Loops/readme.md index 3008b4f..3cdae61 100644 --- a/docs/4-Writing-Functions-Conditionals-and-Loops/readme.md +++ b/docs/4-Writing-Functions-Conditionals-and-Loops/readme.md @@ -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") diff --git a/inst/tutorials/1-Introduction/lesson.Rmd b/inst/tutorials/1-Introduction/lesson.Rmd index e9b363a..4d4f124 100644 --- a/inst/tutorials/1-Introduction/lesson.Rmd +++ b/inst/tutorials/1-Introduction/lesson.Rmd @@ -20,6 +20,7 @@ runtime: shiny_prerendered library(gradethis) library(trainingRIntro) library(shiny) + ``` This lesson is a part of the Introduction to R for Air Quality Data Science. The sections below provide a basic introduction to R, including how to install and set up R and RStudio, an overview of R syntax, and how to perform simple operations. diff --git a/inst/tutorials/2-Functions-and-Importing-Data/lesson.Rmd b/inst/tutorials/2-Functions-and-Importing-Data/lesson.Rmd index 4019b4c..8704c4e 100644 --- a/inst/tutorials/2-Functions-and-Importing-Data/lesson.Rmd +++ b/inst/tutorials/2-Functions-and-Importing-Data/lesson.Rmd @@ -18,6 +18,7 @@ runtime: shiny_prerendered library(gradethis) library(trainingRIntro) library(shiny) + ``` This lesson covers the use of functions in R, including built-in functions and functions from packages. It also discusses how to import diff --git a/inst/tutorials/3-Subsetting-Sorting-and-Combining/lesson.Rmd b/inst/tutorials/3-Subsetting-Sorting-and-Combining/lesson.Rmd index 89d2cf8..b869355 100644 --- a/inst/tutorials/3-Subsetting-Sorting-and-Combining/lesson.Rmd +++ b/inst/tutorials/3-Subsetting-Sorting-and-Combining/lesson.Rmd @@ -17,6 +17,7 @@ runtime: shiny_prerendered library(gradethis) library(trainingRIntro) library(shiny) + ``` This lesson covers how to subset data using indexing, logical operators, and the `filter()` function from `dplyr`. It also covers how to sort and combine data frames. diff --git a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd index bd2f7be..e51509e 100644 --- a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd +++ b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd @@ -17,6 +17,12 @@ runtime: shiny_prerendered library(gradethis) library(trainingRIntro) library(shiny) + print_hello <- function() { + + print("Hello") + +} + ``` This lesson covers how to write your own R functions. It also explains how to automate diff --git a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.html b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.html deleted file mode 100644 index fe7a7fe..0000000 --- a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.html +++ /dev/null @@ -1,1689 +0,0 @@ - - - - - - - - - - - - - - - - - - -4 . Writing Functions, Conditionals, and Loops - - - - - - - - - - - - - - - - - - - - - -Skip to Tutorial Content - - - -
-
- -
- -

This lesson covers how to write your own R functions. It also -explains how to automate your code using if() and -ifelse() functions, for loops, and the apply -function.

-
-

Prerequisites

-

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 or the -region5air package.

-
# Assuming the package is already loaded
-
-data(chicago_air)
-
-
-

Writing Functions

-

As discussed in the second lesson on -functions, R can execute a saved chunk of code by running the name -of a function, like mean(). The name mean is -saved like a variable name, but since the name refers to a function, the -thing that’s saved is not a data object but lines of R code.

-

To save your own function, use this construction:

-
my_function_name <- function() {
-
-  # lines of R code
-
-}
-

We can write a simple function that prints something to the console. -Here is a function named print_hello.

-
-
print_hello <- function() {
-
-  print("Hello")
-
-}
- -
-
-
print_hello()
- -
-
-
-

Arguments

-

Most of the functions we have used in these lessons have had at least -one argument inside of the parentheses. The print_hello() -function did not have any arguments, so we could run it without putting -anything inside (). We could modify the function to take an -argument that pastes some text to the printed message.

-

Here we recreate the same function, but this time we add an argument -text inside of the parentheses.

-
-
print_hello <- function(text) {
-
-  message <- paste("Hello", text)
-
-  print(message)
-
-}
- -
-

Now there are two lines of code inside of the curly braces. The first -line uses the paste() function to concatenate two character -values. The first value will always be “Hello”. The second value will be -supplied by the user in the text argument.

-
-
print_hello(text = "everybody!")
- -
-
-
-

Default Values

-

We can create a function with more than one argument, and set default -values when needed. Suppose we would like to make a function that checks -if a measurement is greater than a criteria pollutant standard. We could -make a simple function that takes two arguments: one for the measurement -value, and one for the standard value.

-
-
standard_violated <- function(measurement, standard) {
-
-  measurement > standard
-
-}
- -
-

This function will simply return a TRUE or -FALSE value, depending on whether the measurement is -greater than the standard or not.

-
-
standard_violated(measurement = 84, standard = 70)
- -
-

We could write a more specific function for checking a value against -the ozone standard. For this function, we want to keep the -standard parameter but make sure the default is -70. It may be that we typically want to use this function -to check against the current 8-hour ozone standard in parts per billion, -but have the flexibility to use a different value.

-

To set a default value, we use = 70 when we create the -function.

-
-
standard_violated <- function(measurement, standard = 70) {
-
-  measurement > standard
-
-}
- -
-

Now, when we use the function, it is not necessary to set the -standard argument.

-
-
standard_violated(measurement = 50)
- -
-
-
-

Positional Arguments

-

One final note on functions in R. When a function is created, the -order of the arguments are important. The user can supply values for the -arguments in the order they appeared in the parentheses of the -function( ){} call, without writing out the argument -names.

-

For example, we can supply two numbers to the -standard_violated() function that we created above, without -writing out the measurement and standard -arguments. When R executes the function, it will assign the numbers to -the arguments based on the position in the parentheses.

-

Here we show that using two numbers in a different order will return -different outputs.

-
-
standard_violated(60, 70)
- -
-
-
standard_violated(70, 60)
- -
-
-
-

if Functions

-

Writing custom functions is a good way to standardize some R code -that can be reused on different data sets. It’s also helpful to write -code that will execute different lines of code depending on different -scenarios. The functions if() and ifelse() -allow you to control what code is executed based on a logical -condition.

-

The if() function takes the logical condition in the -parentheses. The code that will run if the logical expression is -TRUE is placed inside curly braces. Below is the outline -(not actual R code).

-
if(<logical expression>) {
-
-  <code that will run if the logical expression is TRUE>
-
-}
-

The key word else can also be used with another set of -curly braces to hold code that will only run if the logical expression -returns FALSE.

-
if(<logical expression>) {
-
-  <code that will run if the logical expression is true>
-
-} else {
-
-  <code that will run if the logical expression is false>
-
-}
-

For example, if we wanted to print a message based on the value of -ozone, we could use this construction:

-
-
ozone <- 0.075
-
-if(ozone > 0.065) {
-
-  print("Potential Health Effects")
-
-} else {
-
-  print("All Good")
-
-}
- -
-

Since the expression ozone > 0.065 resolves to -TRUE, the code in the first set of curly braces is run. If -we set the ozone variable to 0.06, then the -logical expression will resolve to FALSE and the code in -the second curly braces will run.

-
-
ozone <- 0.06
-
-if(ozone > 0.065) {
-
-  print("Potential Health Effects")
-
-} else {
-
-  print("All Good")
-
-}
- -
-

The ifelse() function is another way to use a logical -condition that determines which output is returned. Here is the -outline

-
ifelse(<test>, <yes>, <no>)
-

The test argument is the logical expression, -yes is the value returned if the expression resolves to -TRUE, and no is the value returned if the -expression resolves to FALSE.

-

Here we accomplish the same task as the previous example. This time -we use the ifelse() function to create a variable named -message.

-
-
ozone_value <- 0.06
-
-message <- ifelse(ozone_value > 0.065, "Potential Health Effects", "All Good")
-
-print(message)
- -
-
-
-

For loops

-

Like most programming languages, R has for and while loops. This -tutorial will cover just for loops and move on to apply() -functions, which are more commonly used in R.

-

For loops are used to repeat an operation a set number of times. Here -is the basic outline:

-
for(i in sequence){
-
-  <code that will run a set number of times>
-
-}
-

The sequence parameter is typically a vector. The -i parameter is a variable that will take on the values in -the sequence vector. For instance, if sequence -was the vector c(1, 2, 3) then the i variable -will take on each of those values in turn.

-

This example simply prints the values of the vector as the for loop -progresses.

-
-
for(i in c(1, 2, 3)) {
-
-  print(i)
-
-}
- -
-

Typically when we use loops, we want to perform the same operation on -different sets of data and save the results. To do this using the -for() function in R, we need to create an empty vector (or -list or data frame) and save the results during each iteration.

-

Here is an example data frame we will use. It represents a few values -from three monitors.

-
-
monitors <- data.frame(monitor1 = c(50, 60, 58, 52),
-                       monitor2 = c(55, 59, 65, 61),
-                       monitor3 = c(70, 62, 68, 71))
-
-monitors
- -
-

In the code below, we create an empty vector called max_values. As -the for() function loops through the vector c(1, 2, 3), the data frame -columns are accessed using square brackets [ , i]. Each max value is -saved to the max_values vector using square brackets [i].

-
-
max_values <- c()
-
-for(i in c(1, 2, 3)) {
-
-  max_values[i] <- max(monitors[, i])
-
-}
-
-max_values
- -
-
-
-

apply function

-

Although the for loop is common in programming languages, it is not -the most efficient way to apply a function to different sets of data in -R. The most efficient way to do loops in R is with the -apply() family of functions, including -lapply(), tapply(), and mapply(). -This section will demonstrate how to use the apply() -function.

-

The apply() function takes a data frame (or matrix) as -the first argument. The second argument determines if each loop will -apply to the rows (1) or columns (2). And the -third argument is the function you want to apply to each row or column. -Additional arguments can be used to pass on to the function being -applied to each row or column.

-

The example below applies the max() function to the -monitors data frame from the previous section.

-
-
monitors_max <- apply(monitors, MARGIN = 2, FUN = max)
-
-monitors_max
- -
-

The MARGIN argument is set to 2 because we are applying the max() -function to the columns of the data frame. Also notice that we do not -need to create an initial empty vector, as we did with the for() -function. The returned value is a named vector that is as long as the -number of columns in the data frame.

-

We could also find the mean of each row in the monitors -data frame. To do this, we would set the MARGIN argument to -1.

-
-
apply(monitors, MARGIN = 1, FUN = mean)
- -
-
-
-

Exercises

-
-

Exercise 1

-

Write a function named ppm_to_ppb that converts a value -from parts per million to parts per billion.

-
-
# Your code here
- -
-
-
# Define the function `ppm_to_ppb` with one argument for the value you want to convert.
-
-
-
# Inside the function, multiply the input value by 1000 to convert it to parts per billion.
-
-
-
# Return the converted value.
-
-
-
ppm_to_ppb <- function(value) {
-  value * 1000
-}
-
-
-
-

Exercise 2

-

Write a function named check_value that prints “warning” -if a value is above a threshold, and “OK” if it’s below. Make the -threshold an argument in the function.

-
-
# Your code here
- -
-
-
# Define the function `check_value` with two arguments: `value` and `threshold`.
-
-
-
# Use an `if` statement to check if `value` is greater than `threshold`.
-
-
-
# Print "warning" if the value is above the threshold, otherwise print "OK".
-
-
-
check_value <- function(value, threshold) {
-  if(value > threshold) {
-    print("warning")
-  } else {
-    print("OK")
-  }
-}
-
-
-
-

Exercise 3

-

Use the for() function to loop through the -temp column of the data from this package and print any -value that is above 90 degrees.

-
-
# Your code here
- -
-
-
# Access the `temp` column of the data frame within the loop.
-
-
-
# Use a `for` loop to iterate over each value in the `temp` column.
-
-
-
# Inside the loop, use an `if` statement to check if the current temperature value is greater than 90.
-
-
-
# If a value is above 90, use `print()` to display it.
-
-
-
for (i in chicago_air$temp) {
-  if(i > 90) {
-    print(i)
-  }
-}
-
-
-
-

Exercise 4

-

Use the apply() function to create a vector of the mean -values from the numeric columns in the data from this package.

-
-
# Your code here
- -
-
-
# First, subset the data frame to include only the numeric columns you wish to analyze.
-
-
-
# Use the `apply()` function with the subsetted data frame, specifying `MARGIN = 2` to apply the function across columns.
-
-
-
# Use the `mean` function as the `FUN` argument, including `na.rm = TRUE` to handle missing values.
-
-
-
chicago_numeric <- chicago_air[, c("ozone", "temp", "pressure")]
-mean_values <- apply(chicago_numeric, MARGIN = 2, FUN = mean, na.rm = TRUE)
-mean_values
-
-
-
-
-

Next Lesson

-

You have completed Lesson . Click the button below to mark it as -complete and move on to the next lesson.

- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - -
- -
- -
-
-
-
- - -
-

4 . Writing -Functions, Conditionals, and Loops

-

Fluent Data, LLC

-

2024-05-05

-
- - -
-
-
-
- - -
-
- - - - - - - - - - - - - - - - diff --git a/inst/tutorials/5-Plotting/lesson.Rmd b/inst/tutorials/5-Plotting/lesson.Rmd index 304752b..58131b9 100644 --- a/inst/tutorials/5-Plotting/lesson.Rmd +++ b/inst/tutorials/5-Plotting/lesson.Rmd @@ -17,6 +17,7 @@ runtime: shiny_prerendered library(gradethis) library(trainingRIntro) library(shiny) + ``` In this lesson you will first learn how to quickly visualize data using a few base diff --git a/inst/tutorials/6-Basic-Statistics/lesson.Rmd b/inst/tutorials/6-Basic-Statistics/lesson.Rmd index c05fb24..5f2b89f 100644 --- a/inst/tutorials/6-Basic-Statistics/lesson.Rmd +++ b/inst/tutorials/6-Basic-Statistics/lesson.Rmd @@ -17,6 +17,7 @@ runtime: shiny_prerendered library(gradethis) library(trainingRIntro) library(shiny) + ``` diff --git a/inst/tutorials/7-Quality-Assurance/lesson.Rmd b/inst/tutorials/7-Quality-Assurance/lesson.Rmd index 6c7e136..e113b38 100644 --- a/inst/tutorials/7-Quality-Assurance/lesson.Rmd +++ b/inst/tutorials/7-Quality-Assurance/lesson.Rmd @@ -17,6 +17,7 @@ runtime: shiny_prerendered library(gradethis) library(trainingRIntro) library(shiny) + ``` Quality assurance (QA) in R could refer to at least two things: the quality of the code, or the quality of the data. Advanced R users that develop their own functions should follow general best practices for software development. The package [testthat](https://testthat.r-lib.org/) is useful to ensure that functions are working the way they are intended to work. However, this lesson focuses on _data_ quality, and points out a few common mistakes when using R. diff --git a/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml b/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml index f2ee345..2843125 100644 --- a/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml +++ b/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml @@ -10,7 +10,12 @@ lesson: next: 5-Plotting closing: | Well done on completing Writing Functions, Conditionals, and Loops! You've developed the skills to customize your analysis and automate tasks in R. Next, you'll move on to Plotting in R, where you'll learn how to visually represent data using various plotting techniques. Get ready to bring your data to life with engaging visuals! +setup: | + print_hello <- function() { + print("Hello") + + } introduction: | This lesson covers how to write your own R functions. It also explains how to automate your code using `if()` and `ifelse()` functions, for loops, and the `apply` From 193d09edbae4a3a688277b5af2aa82474dbc184a Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Sun, 5 May 2024 18:04:27 -0400 Subject: [PATCH 6/7] gave all tutorials ids to assist with resetting and created reset_lesson and reset_tutorial functions. --- R/reset_lessons.R | 76 + .../lesson.Rmd | 6 + .../lesson.html | 1735 +++++++++++++++++ .../lesson2.yaml | 3 + .../lesson3.yaml | 3 + .../lesson4.yaml | 3 + source/5-Plotting/lesson5.yaml | 3 + source/6-Basic-Statistics/lesson6.yaml | 3 + source/7-Quality-Assurance/lesson7.yaml | 3 + 9 files changed, 1835 insertions(+) create mode 100644 R/reset_lessons.R create mode 100644 inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.html diff --git a/R/reset_lessons.R b/R/reset_lessons.R new file mode 100644 index 0000000..dd10ce5 --- /dev/null +++ b/R/reset_lessons.R @@ -0,0 +1,76 @@ +#' 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()) + } + +} diff --git a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd index e51509e..0b66734 100644 --- a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd +++ b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd @@ -29,6 +29,12 @@ This lesson covers how to write your own R functions. It also explains how to au your code using `if()` and `ifelse()` functions, for loops, and the `apply` function. +```{r test} + +print(options("tutorial.storage")) + +``` + ## Prerequisites This lesson assumes you are familiar with the material in the previous lessons: diff --git a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.html b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.html new file mode 100644 index 0000000..6679b9b --- /dev/null +++ b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.html @@ -0,0 +1,1735 @@ + + + + + + + + + + + + + + + + + + +4 . Writing Functions, Conditionals, and Loops + + + + + + + + + + + + + + + + + + + + + +Skip to Tutorial Content + + + +
+
+ +
+ +

This lesson covers how to write your own R functions. It also +explains how to automate your code using if() and +ifelse() functions, for loops, and the apply +function.

+
print(options("tutorial.storage"))
+
## $tutorial.storage
+## NULL
+
+

Prerequisites

+

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 or the +region5air package.

+
# Assuming the package is already loaded
+
+data(chicago_air)
+
+
+

Writing Functions

+

As discussed in the second lesson on +functions, R can execute a saved chunk of code by running the name +of a function, like mean(). The name mean is +saved like a variable name, but since the name refers to a function, the +thing that’s saved is not a data object but lines of R code.

+

To save your own function, use this construction:

+
my_function_name <- function() {
+
+  # lines of R code
+
+}
+

We can write a simple function that prints something to the console. +Here is a function named print_hello.

+
+
print_hello <- function() {
+
+  print("Hello")
+
+}
+ +
+
+
print_hello()
+ +
+
+
+

Arguments

+

Most of the functions we have used in these lessons have had at least +one argument inside of the parentheses. The print_hello() +function did not have any arguments, so we could run it without putting +anything inside (). We could modify the function to take an +argument that pastes some text to the printed message.

+

Here we recreate the same function, but this time we add an argument +text inside of the parentheses.

+
+
print_hello <- function(text) {
+
+  message <- paste("Hello", text)
+
+  print(message)
+
+}
+ +
+

Now there are two lines of code inside of the curly braces. The first +line uses the paste() function to concatenate two character +values. The first value will always be “Hello”. The second value will be +supplied by the user in the text argument.

+
+
print_hello(text = "everybody!")
+ +
+
+
+

Default Values

+

We can create a function with more than one argument, and set default +values when needed. Suppose we would like to make a function that checks +if a measurement is greater than a criteria pollutant standard. We could +make a simple function that takes two arguments: one for the measurement +value, and one for the standard value.

+
+
standard_violated <- function(measurement, standard) {
+
+  measurement > standard
+
+}
+ +
+

This function will simply return a TRUE or +FALSE value, depending on whether the measurement is +greater than the standard or not.

+
+
standard_violated(measurement = 84, standard = 70)
+ +
+

We could write a more specific function for checking a value against +the ozone standard. For this function, we want to keep the +standard parameter but make sure the default is +70. It may be that we typically want to use this function +to check against the current 8-hour ozone standard in parts per billion, +but have the flexibility to use a different value.

+

To set a default value, we use = 70 when we create the +function.

+
+
standard_violated <- function(measurement, standard = 70) {
+
+  measurement > standard
+
+}
+ +
+

Now, when we use the function, it is not necessary to set the +standard argument.

+
+
standard_violated(measurement = 50)
+ +
+
+
+

Positional Arguments

+

One final note on functions in R. When a function is created, the +order of the arguments are important. The user can supply values for the +arguments in the order they appeared in the parentheses of the +function( ){} call, without writing out the argument +names.

+

For example, we can supply two numbers to the +standard_violated() function that we created above, without +writing out the measurement and standard +arguments. When R executes the function, it will assign the numbers to +the arguments based on the position in the parentheses.

+

Here we show that using two numbers in a different order will return +different outputs.

+
+
standard_violated(60, 70)
+ +
+
+
standard_violated(70, 60)
+ +
+
+
+

if Functions

+

Writing custom functions is a good way to standardize some R code +that can be reused on different data sets. It’s also helpful to write +code that will execute different lines of code depending on different +scenarios. The functions if() and ifelse() +allow you to control what code is executed based on a logical +condition.

+

The if() function takes the logical condition in the +parentheses. The code that will run if the logical expression is +TRUE is placed inside curly braces. Below is the outline +(not actual R code).

+
if(<logical expression>) {
+
+  <code that will run if the logical expression is TRUE>
+
+}
+

The key word else can also be used with another set of +curly braces to hold code that will only run if the logical expression +returns FALSE.

+
if(<logical expression>) {
+
+  <code that will run if the logical expression is true>
+
+} else {
+
+  <code that will run if the logical expression is false>
+
+}
+

For example, if we wanted to print a message based on the value of +ozone, we could use this construction:

+
+
ozone <- 0.075
+
+if(ozone > 0.065) {
+
+  print("Potential Health Effects")
+
+} else {
+
+  print("All Good")
+
+}
+ +
+

Since the expression ozone > 0.065 resolves to +TRUE, the code in the first set of curly braces is run. If +we set the ozone variable to 0.06, then the +logical expression will resolve to FALSE and the code in +the second curly braces will run.

+
+
ozone <- 0.06
+
+if(ozone > 0.065) {
+
+  print("Potential Health Effects")
+
+} else {
+
+  print("All Good")
+
+}
+ +
+

The ifelse() function is another way to use a logical +condition that determines which output is returned. Here is the +outline

+
ifelse(<test>, <yes>, <no>)
+

The test argument is the logical expression, +yes is the value returned if the expression resolves to +TRUE, and no is the value returned if the +expression resolves to FALSE.

+

Here we accomplish the same task as the previous example. This time +we use the ifelse() function to create a variable named +message.

+
+
ozone_value <- 0.06
+
+message <- ifelse(ozone_value > 0.065, "Potential Health Effects", "All Good")
+
+print(message)
+ +
+
+
+

For loops

+

Like most programming languages, R has for and while loops. This +tutorial will cover just for loops and move on to apply() +functions, which are more commonly used in R.

+

For loops are used to repeat an operation a set number of times. Here +is the basic outline:

+
for(i in sequence){
+
+  <code that will run a set number of times>
+
+}
+

The sequence parameter is typically a vector. The +i parameter is a variable that will take on the values in +the sequence vector. For instance, if sequence +was the vector c(1, 2, 3) then the i variable +will take on each of those values in turn.

+

This example simply prints the values of the vector as the for loop +progresses.

+
+
for(i in c(1, 2, 3)) {
+
+  print(i)
+
+}
+ +
+

Typically when we use loops, we want to perform the same operation on +different sets of data and save the results. To do this using the +for() function in R, we need to create an empty vector (or +list or data frame) and save the results during each iteration.

+

Here is an example data frame we will use. It represents a few values +from three monitors.

+
+
monitors <- data.frame(monitor1 = c(50, 60, 58, 52),
+                       monitor2 = c(55, 59, 65, 61),
+                       monitor3 = c(70, 62, 68, 71))
+
+monitors
+ +
+

In the code below, we create an empty vector called max_values. As +the for() function loops through the vector c(1, 2, 3), the data frame +columns are accessed using square brackets [ , i]. Each max value is +saved to the max_values vector using square brackets [i].

+
+
max_values <- c()
+
+for(i in c(1, 2, 3)) {
+
+  max_values[i] <- max(monitors[, i])
+
+}
+
+max_values
+ +
+
+
+

apply function

+

Although the for loop is common in programming languages, it is not +the most efficient way to apply a function to different sets of data in +R. The most efficient way to do loops in R is with the +apply() family of functions, including +lapply(), tapply(), and mapply(). +This section will demonstrate how to use the apply() +function.

+

The apply() function takes a data frame (or matrix) as +the first argument. The second argument determines if each loop will +apply to the rows (1) or columns (2). And the +third argument is the function you want to apply to each row or column. +Additional arguments can be used to pass on to the function being +applied to each row or column.

+

The example below applies the max() function to the +monitors data frame from the previous section.

+
+
monitors_max <- apply(monitors, MARGIN = 2, FUN = max)
+
+monitors_max
+ +
+

The MARGIN argument is set to 2 because we are applying the max() +function to the columns of the data frame. Also notice that we do not +need to create an initial empty vector, as we did with the for() +function. The returned value is a named vector that is as long as the +number of columns in the data frame.

+

We could also find the mean of each row in the monitors +data frame. To do this, we would set the MARGIN argument to +1.

+
+
apply(monitors, MARGIN = 1, FUN = mean)
+ +
+
+
+

Exercises

+
+

Exercise 1

+

Write a function named ppm_to_ppb that converts a value +from parts per million to parts per billion.

+
+
# Your code here
+ +
+
+
# Define the function `ppm_to_ppb` with one argument for the value you want to convert.
+
+
+
# Inside the function, multiply the input value by 1000 to convert it to parts per billion.
+
+
+
# Return the converted value.
+
+
+
ppm_to_ppb <- function(value) {
+  value * 1000
+}
+
+
+
+

Exercise 2

+

Write a function named check_value that prints “warning” +if a value is above a threshold, and “OK” if it’s below. Make the +threshold an argument in the function.

+
+
# Your code here
+ +
+
+
# Define the function `check_value` with two arguments: `value` and `threshold`.
+
+
+
# Use an `if` statement to check if `value` is greater than `threshold`.
+
+
+
# Print "warning" if the value is above the threshold, otherwise print "OK".
+
+
+
check_value <- function(value, threshold) {
+  if(value > threshold) {
+    print("warning")
+  } else {
+    print("OK")
+  }
+}
+
+
+
+

Exercise 3

+

Use the for() function to loop through the +temp column of the data from this package and print any +value that is above 90 degrees.

+
+
# Your code here
+ +
+
+
# Access the `temp` column of the data frame within the loop.
+
+
+
# Use a `for` loop to iterate over each value in the `temp` column.
+
+
+
# Inside the loop, use an `if` statement to check if the current temperature value is greater than 90.
+
+
+
# If a value is above 90, use `print()` to display it.
+
+
+
for (i in chicago_air$temp) {
+  if(i > 90) {
+    print(i)
+  }
+}
+
+
+
+

Exercise 4

+

Use the apply() function to create a vector of the mean +values from the numeric columns in the data from this package.

+
+
# Your code here
+ +
+
+
# First, subset the data frame to include only the numeric columns you wish to analyze.
+
+
+
# Use the `apply()` function with the subsetted data frame, specifying `MARGIN = 2` to apply the function across columns.
+
+
+
# Use the `mean` function as the `FUN` argument, including `na.rm = TRUE` to handle missing values.
+
+
+
chicago_numeric <- chicago_air[, c("ozone", "temp", "pressure")]
+mean_values <- apply(chicago_numeric, MARGIN = 2, FUN = mean, na.rm = TRUE)
+mean_values
+
+
+
+
+

Next Lesson

+

You have completed Lesson . Click the button below to mark it as +complete and move on to the next lesson.

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + + +
+ +
+ +
+
+
+
+ + +
+

4 . Writing +Functions, Conditionals, and Loops

+

Fluent Data, LLC

+

2024-05-05

+
+ + +
+
+
+
+ + +
+
+ + + + + + + + + + + + + + + + diff --git a/source/2-Functions-and-Importing-Data/lesson2.yaml b/source/2-Functions-and-Importing-Data/lesson2.yaml index 8aaf6f1..0cb6bde 100644 --- a/source/2-Functions-and-Importing-Data/lesson2.yaml +++ b/source/2-Functions-and-Importing-Data/lesson2.yaml @@ -3,6 +3,9 @@ title: "Functions and Importing Data" metadata: author: Fluent Data, LLC date: "`r Sys.Date()`" + tutorial: + id: "training.r.intro.2" + version: 1.0 description: | This lesson provides an overview of using functions in R, including built-in and package functions, and demonstrates how to import data from CSV and Excel files. diff --git a/source/3-Subsetting-Sorting-and-Combining/lesson3.yaml b/source/3-Subsetting-Sorting-and-Combining/lesson3.yaml index 100b977..9ccf642 100644 --- a/source/3-Subsetting-Sorting-and-Combining/lesson3.yaml +++ b/source/3-Subsetting-Sorting-and-Combining/lesson3.yaml @@ -2,6 +2,9 @@ title: "Subsetting, Sorting, and Combining Data Frames" metadata: author: Fluent Data, LLC date: "`r Sys.Date()`" + tutorial: + id: "training.r.intro.3" + version: 1.0 description: | This lesson provides an overview of subsetting, sorting, and combining data frames in R using indexing, logical operations, the filter() function from dplyr, as well as sorting with arrange() and combining data frames with bind_rows(). lesson: diff --git a/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml b/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml index 2843125..131eeee 100644 --- a/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml +++ b/source/4-Writing-Functions-Conditionals-and-Loops/lesson4.yaml @@ -2,6 +2,9 @@ title: "Writing Functions, Conditionals, and Loops" metadata: author: Fluent Data, LLC date: "`r Sys.Date()`" + tutorial: + id: "training.r.intro.4" + version: 1.0 description: | This lesson teaches how to create custom R functions, use conditional statements to make decisions in your code, loop through data with for loops, and efficiently apply functions to data structures using the apply function. lesson: diff --git a/source/5-Plotting/lesson5.yaml b/source/5-Plotting/lesson5.yaml index 750f68a..c963373 100644 --- a/source/5-Plotting/lesson5.yaml +++ b/source/5-Plotting/lesson5.yaml @@ -2,6 +2,9 @@ title: "Plotting in R" metadata: author: Fluent Data, LLC date: "`r Sys.Date()`" + tutorial: + id: "training.r.intro.5" + version: 1.0 description: | This lesson introduces the basics of plotting in R using base plot functions and the ggplot2 package, covering how to visualize data with scatter plots, line graphs, histograms, and box plots, including facets and fitted lines. lesson: diff --git a/source/6-Basic-Statistics/lesson6.yaml b/source/6-Basic-Statistics/lesson6.yaml index 8bf6563..a297aff 100644 --- a/source/6-Basic-Statistics/lesson6.yaml +++ b/source/6-Basic-Statistics/lesson6.yaml @@ -2,6 +2,9 @@ title: "Basic Statistics" metadata: author: Fluent Data, LLC date: "`r Sys.Date()`" + tutorial: + id: "training.r.intro.6" + version: 1.0 description: | This lesson introduces basic statistical analysis in R, covering descriptive statistics, measures of central tendency and dispersion, statistical tests like the t-test and Shapiro-Wilk test for normality, correlation analysis with the cor() and cor.test() functions, and visualization of relationships between variables using pairwise plots. lesson: diff --git a/source/7-Quality-Assurance/lesson7.yaml b/source/7-Quality-Assurance/lesson7.yaml index 134cdd5..8daa623 100644 --- a/source/7-Quality-Assurance/lesson7.yaml +++ b/source/7-Quality-Assurance/lesson7.yaml @@ -2,6 +2,9 @@ title: "Quality Assurance and Common Pitfalls" metadata: author: Fluent Data, LLC date: "`r Sys.Date()`" + tutorial: + id: "training.r.intro.7" + version: 1.0 description: | This lesson covers quality assurance for data in R, focusing on ensuring the integrity and consistency of data types, managing unallowed values, and handling outliers. It also points out common mistakes and how to address them, emphasizing the importance of accurately understanding and manipulating data to ensure reliable analysis outcomes. lesson: From 6279b41ac47c9964b2e84fb4954e7fb089ebe97e Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Sun, 5 May 2024 18:51:43 -0400 Subject: [PATCH 7/7] Added reset functionality, fixed a bunch of bugs. --- R/build_learnr.R | 19 +- R/reset_lessons.R | 2 + docs/1-Introduction/readme.md | 6 +- docs/2-Functions-and-Importing-Data/readme.md | 4 +- .../readme.md | 2 +- docs/5-Plotting/readme.md | 4 +- docs/6-Basic-Statistics/readme.md | 2 +- inst/tutorials/1-Introduction/lesson.Rmd | 34 +++- inst/tutorials/1-Introduction/lesson.html | 191 ++++++++++++------ .../2-Functions-and-Importing-Data/lesson.Rmd | 7 +- .../lesson.Rmd | 5 +- .../lesson.Rmd | 9 +- inst/tutorials/5-Plotting/lesson.Rmd | 7 +- inst/tutorials/6-Basic-Statistics/lesson.Rmd | 5 +- inst/tutorials/7-Quality-Assurance/lesson.Rmd | 3 + source/1-Introduction/lesson1.yaml | 25 +++ 16 files changed, 236 insertions(+), 89 deletions(-) diff --git a/R/build_learnr.R b/R/build_learnr.R index 33ad945..8297321 100644 --- a/R/build_learnr.R +++ b/R/build_learnr.R @@ -210,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") @@ -277,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") @@ -294,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) diff --git a/R/reset_lessons.R b/R/reset_lessons.R index dd10ce5..fa23d93 100644 --- a/R/reset_lessons.R +++ b/R/reset_lessons.R @@ -73,4 +73,6 @@ reset_training <- function() { file.remove(user_state_file()) } + return(invisible(TRUE)) + } diff --git a/docs/1-Introduction/readme.md b/docs/1-Introduction/readme.md index a790df8..65a6ca3 100644 --- a/docs/1-Introduction/readme.md +++ b/docs/1-Introduction/readme.md @@ -125,7 +125,7 @@ about what variables you're working with during your R session. ## Basic Math -Open up a script if you haven't already (“File” -> “New File” -> “R Script”). Try some math by either typing the lines below or copying and pasting +Open up a script if you haven't already (File -> New File -> R Script). Try some math by either typing the lines below or copying and pasting the lines into your script. @@ -143,7 +143,7 @@ in the R language. | Operator | Meaning | Example | -|: --- | --- | --- | +| :--- | :--- | :--- | | + | addition | 2 + 2 | | - | subtraction | 2 - 2 | | * | multiplication | 2 * 2 | @@ -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` | diff --git a/docs/2-Functions-and-Importing-Data/readme.md b/docs/2-Functions-and-Importing-Data/readme.md index 5c1fcad..4880f4e 100644 --- a/docs/2-Functions-and-Importing-Data/readme.md +++ b/docs/2-Functions-and-Importing-Data/readme.md @@ -239,7 +239,7 @@ mean(seq(from=1, to=10, by=3)) ``` -_Note: Typically you don’t want to have too many nested functions because it becomes difficult to read._ +_Note: Typically you dont want to have too many nested functions because it becomes difficult to read._ ## NA Values @@ -322,7 +322,7 @@ serialCorrelationTest(x) Here is a link to a page that lists many useful packages for environmental data analysis: https://cran.r-project.org/web/views/Environmetrics.html -Remember, when you close down RStudio, then start it up again, you don’t have to download the package again. But you do have to use the `library()` function to load the package before you can use any function that's not in the R core functionality (this is very easy to forget). +Remember, when you close down RStudio, then start it up again, you dont have to download the package again. But you do have to use the `library()` function to load the package before you can use any function that's not in the R core functionality (this is very easy to forget). ## Importing Data diff --git a/docs/3-Subsetting-Sorting-and-Combining/readme.md b/docs/3-Subsetting-Sorting-and-Combining/readme.md index d83792b..5471a26 100644 --- a/docs/3-Subsetting-Sorting-and-Combining/readme.md +++ b/docs/3-Subsetting-Sorting-and-Combining/readme.md @@ -161,7 +161,7 @@ my_data[3, 2] ``` -We can also access data from a vector using the same indexing idea. In this case, you don’t need the comma to separate the rows and columns since you are accessing one dimensional data. Below is a vector of numbers. +We can also access data from a vector using the same indexing idea. In this case, you dont need the comma to separate the rows and columns since you are accessing one dimensional data. Below is a vector of numbers. ```{r ex-81d6c088db05, exercise = FALSE, exercise.eval = TRUE, exercise.cap = 'Vector Indexing Example'} diff --git a/docs/5-Plotting/readme.md b/docs/5-Plotting/readme.md index 24fe85b..1a2441f 100644 --- a/docs/5-Plotting/readme.md +++ b/docs/5-Plotting/readme.md @@ -223,7 +223,7 @@ Additional modifications can be made. Customize it by adding color, title, and l ggplot(chicago_air, aes(x = temp, y = ozone)) + geom_point(color = "forestgreen") + ggtitle('Relationship between Ozone and Temperature') + - xlab('Temperature (°F)') + + xlab('Temperature (F)') + ylab('Ozone (ppm)') ``` @@ -238,7 +238,7 @@ argument `color` in the `aes( )` function. ggplot(chicago_air, aes(x = temp, y = ozone, color = factor(month))) + geom_point() + ggtitle('Relationship between Ozone and Temperature') + - xlab('Temperature (°F)') + + xlab('Temperature (F)') + ylab('Ozone (ppm)') ``` diff --git a/docs/6-Basic-Statistics/readme.md b/docs/6-Basic-Statistics/readme.md index 1afcbb2..c315c9a 100644 --- a/docs/6-Basic-Statistics/readme.md +++ b/docs/6-Basic-Statistics/readme.md @@ -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()` | diff --git a/inst/tutorials/1-Introduction/lesson.Rmd b/inst/tutorials/1-Introduction/lesson.Rmd index 4d4f124..7aed79d 100644 --- a/inst/tutorials/1-Introduction/lesson.Rmd +++ b/inst/tutorials/1-Introduction/lesson.Rmd @@ -66,7 +66,7 @@ a programming language. ## Basic Math -Open up a script if you haven't already (“File” -> “New File” -> “R Script”). Try some math by either typing the lines below or copying and pasting +Open up a script if you haven't already (File -> New File -> R Script). Try some math by either typing the lines below or copying and pasting the lines into your script. @@ -84,7 +84,7 @@ in the R language. | Operator | Meaning | Example | -|: --- | --- | --- | +| :--- | :--- | :--- | | + | addition | 2 + 2 | | - | subtraction | 2 - 2 | | * | multiplication | 2 * 2 | @@ -205,7 +205,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` | @@ -474,9 +474,31 @@ df <- data.frame(name = c('Alice', 'Bob', 'Charlie'), age = c(25, 32, 28)) ``` ```{r exercise5-check} -grade_this_code( - correct = c(gradethis::random_praise(), "In R, we can combine vectors of equal length into a data frame using the `data.frame()` function. Here, we're creating two vectors, `name` and `age`, and combining them into a data frame, demonstrating how to organize and structure data in a tabular format. ") -) +grade_this({ + # The student's solution + df_student <- .result + + # Expected names + expected_names <- c('Alice', 'Bob', 'Charlie') + + # Check that the data frame has the correct structure + has_correct_columns <- all(names(df_student) == c('name', 'age')) + contains_all_names <- all(expected_names %in% df_student$name) + are_ages_numeric <- is.numeric(df_student$age) + + # Provide detailed feedback based on specific issues + if (!has_correct_columns) { + fail("Incorrect columns. Ensure your data frame has exactly two columns named `name` and `age`.") + } else if (!contains_all_names) { + missing_names <- setdiff(expected_names, df_student$name) + fail(paste("Missing the following names:", paste(missing_names, collapse = ", "))) + } else if (!are_ages_numeric) { + fail("The `age` column should contain numeric values only. Ensure all ages are numbers.") + } else { + pass("Correct! You've successfully created a data frame with the names 'Alice', 'Bob', and 'Charlie', and ensured that ages are numeric.") + } +}) + ``` diff --git a/inst/tutorials/1-Introduction/lesson.html b/inst/tutorials/1-Introduction/lesson.html index 73594a9..b629cb7 100644 --- a/inst/tutorials/1-Introduction/lesson.html +++ b/inst/tutorials/1-Introduction/lesson.html @@ -14,7 +14,7 @@ - + 1 . Introduction to R @@ -164,9 +164,11 @@

Why Use a Programming Language?

Basic Math

-

Open up a script if you haven’t already (“File” -> “New File” --> “R Script”). Try some math by either typing the lines below or -copying and pasting the lines into your script.

+

Open up a script if you haven’t already +(<U+201C>File<U+201D> -> <U+201C>New +File<U+201D> -> <U+201C>R Script<U+201D>). Try some +math by either typing the lines below or copying and pasting the lines +into your script.

10 + 5
## [1] 15
10 - 5
@@ -180,10 +182,42 @@

Basic Math

Remember, to run the lines, highlight your code and click the “Run” button on the toolbar of the script panel. Below is a table of the math operators in the R language.

-
Operator | Meaning | Example |
-

|: — | — | — | | + | addition | 2 + 2 | | - | subtraction | 2 - 2 | | -* | multiplication | 2 * 2 | | / | division | 2 / 2 | | ^ | -exponentiation | 2 ^ 2 |

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperatorMeaningExample
+addition2 + 2
-subtraction2 - 2
*multiplication2 * 2
/division2 / 2
^exponentiation2 ^ 2

Order of Operations

R follows the usual order of arithmetical operations and uses @@ -276,11 +310,33 @@

Variables

Data Types

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 |

+ + + + + + + + + + + + + + + + + + + + + + + + + +
TypeDescriptionExamples
characterletters and wordsz, red, H2O
numericnumbers1, 3.14, +log(10)
logicalbinaryTRUE, FALSE

The character type requires single or double quotes. The numeric type must be unquoted numbers, and the full-caps logical values TRUE and FALSE must also be unquoted.

@@ -600,6 +656,7 @@

Next Lesson

library(gradethis) library(trainingRIntro) library(shiny) +
diff --git a/inst/tutorials/2-Functions-and-Importing-Data/lesson.Rmd b/inst/tutorials/2-Functions-and-Importing-Data/lesson.Rmd index 8704c4e..910d855 100644 --- a/inst/tutorials/2-Functions-and-Importing-Data/lesson.Rmd +++ b/inst/tutorials/2-Functions-and-Importing-Data/lesson.Rmd @@ -1,6 +1,9 @@ --- author: Fluent Data, LLC date: '`r Sys.Date()`' +tutorial: + id: training.r.intro.2 + version: 1.0 description: | This lesson provides an overview of using functions in R, including built-in and package functions, and demonstrates how to import data from CSV and Excel files. @@ -233,7 +236,7 @@ mean(seq(from=1, to=10, by=3)) ``` -_Note: Typically you don’t want to have too many nested functions because it becomes difficult to read._ +_Note: Typically you dont want to have too many nested functions because it becomes difficult to read._ ## NA Values @@ -316,7 +319,7 @@ serialCorrelationTest(x) Here is a link to a page that lists many useful packages for environmental data analysis: https://cran.r-project.org/web/views/Environmetrics.html -Remember, when you close down RStudio, then start it up again, you don’t have to download the package again. But you do have to use the `library()` function to load the package before you can use any function that's not in the R core functionality (this is very easy to forget). +Remember, when you close down RStudio, then start it up again, you dont have to download the package again. But you do have to use the `library()` function to load the package before you can use any function that's not in the R core functionality (this is very easy to forget). ## Importing Data diff --git a/inst/tutorials/3-Subsetting-Sorting-and-Combining/lesson.Rmd b/inst/tutorials/3-Subsetting-Sorting-and-Combining/lesson.Rmd index b869355..d00f7da 100644 --- a/inst/tutorials/3-Subsetting-Sorting-and-Combining/lesson.Rmd +++ b/inst/tutorials/3-Subsetting-Sorting-and-Combining/lesson.Rmd @@ -1,6 +1,9 @@ --- author: Fluent Data, LLC date: '`r Sys.Date()`' +tutorial: + id: training.r.intro.3 + version: 1.0 description: | This lesson provides an overview of subsetting, sorting, and combining data frames in R using indexing, logical operations, the filter() function from dplyr, as well as sorting with arrange() and combining data frames with bind_rows(). title: 3 . Subsetting, Sorting, and Combining Data Frames @@ -163,7 +166,7 @@ my_data[3, 2] ``` -We can also access data from a vector using the same indexing idea. In this case, you don’t need the comma to separate the rows and columns since you are accessing one dimensional data. Below is a vector of numbers. +We can also access data from a vector using the same indexing idea. In this case, you dont need the comma to separate the rows and columns since you are accessing one dimensional data. Below is a vector of numbers. ```{r ex-81d6c088db05, exercise = FALSE, exercise.eval = TRUE, exercise.cap = 'Vector Indexing Example'} diff --git a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd index 0b66734..c0bd724 100644 --- a/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd +++ b/inst/tutorials/4-Writing-Functions-Conditionals-and-Loops/lesson.Rmd @@ -1,6 +1,9 @@ --- author: Fluent Data, LLC date: '`r Sys.Date()`' +tutorial: + id: training.r.intro.4 + version: 1.0 description: | This lesson teaches how to create custom R functions, use conditional statements to make decisions in your code, loop through data with for loops, and efficiently apply functions to data structures using the apply function. title: 4 . Writing Functions, Conditionals, and Loops @@ -29,12 +32,6 @@ This lesson covers how to write your own R functions. It also explains how to au your code using `if()` and `ifelse()` functions, for loops, and the `apply` function. -```{r test} - -print(options("tutorial.storage")) - -``` - ## Prerequisites This lesson assumes you are familiar with the material in the previous lessons: diff --git a/inst/tutorials/5-Plotting/lesson.Rmd b/inst/tutorials/5-Plotting/lesson.Rmd index 58131b9..504a23e 100644 --- a/inst/tutorials/5-Plotting/lesson.Rmd +++ b/inst/tutorials/5-Plotting/lesson.Rmd @@ -1,6 +1,9 @@ --- author: Fluent Data, LLC date: '`r Sys.Date()`' +tutorial: + id: training.r.intro.5 + version: 1.0 description: | This lesson introduces the basics of plotting in R using base plot functions and the ggplot2 package, covering how to visualize data with scatter plots, line graphs, histograms, and box plots, including facets and fitted lines. title: 5 . Plotting in R @@ -224,7 +227,7 @@ Additional modifications can be made. Customize it by adding color, title, and l ggplot(chicago_air, aes(x = temp, y = ozone)) + geom_point(color = "forestgreen") + ggtitle('Relationship between Ozone and Temperature') + - xlab('Temperature (°F)') + + xlab('Temperature (F)') + ylab('Ozone (ppm)') ``` @@ -239,7 +242,7 @@ argument `color` in the `aes( )` function. ggplot(chicago_air, aes(x = temp, y = ozone, color = factor(month))) + geom_point() + ggtitle('Relationship between Ozone and Temperature') + - xlab('Temperature (°F)') + + xlab('Temperature (F)') + ylab('Ozone (ppm)') ``` diff --git a/inst/tutorials/6-Basic-Statistics/lesson.Rmd b/inst/tutorials/6-Basic-Statistics/lesson.Rmd index 5f2b89f..e83048d 100644 --- a/inst/tutorials/6-Basic-Statistics/lesson.Rmd +++ b/inst/tutorials/6-Basic-Statistics/lesson.Rmd @@ -1,6 +1,9 @@ --- author: Fluent Data, LLC date: '`r Sys.Date()`' +tutorial: + id: training.r.intro.6 + version: 1.0 description: | This lesson introduces basic statistical analysis in R, covering descriptive statistics, measures of central tendency and dispersion, statistical tests like the t-test and Shapiro-Wilk test for normality, correlation analysis with the cor() and cor.test() functions, and visualization of relationships between variables using pairwise plots. title: 6 . Basic Statistics @@ -224,7 +227,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()` | diff --git a/inst/tutorials/7-Quality-Assurance/lesson.Rmd b/inst/tutorials/7-Quality-Assurance/lesson.Rmd index e113b38..ab697b8 100644 --- a/inst/tutorials/7-Quality-Assurance/lesson.Rmd +++ b/inst/tutorials/7-Quality-Assurance/lesson.Rmd @@ -1,6 +1,9 @@ --- author: Fluent Data, LLC date: '`r Sys.Date()`' +tutorial: + id: training.r.intro.7 + version: 1.0 description: | This lesson covers quality assurance for data in R, focusing on ensuring the integrity and consistency of data types, managing unallowed values, and handling outliers. It also points out common mistakes and how to address them, emphasizing the importance of accurately understanding and manipulating data to ensure reliable analysis outcomes. title: 7 . Quality Assurance and Common Pitfalls diff --git a/source/1-Introduction/lesson1.yaml b/source/1-Introduction/lesson1.yaml index d1d0716..d675401 100644 --- a/source/1-Introduction/lesson1.yaml +++ b/source/1-Introduction/lesson1.yaml @@ -545,6 +545,31 @@ exercises: In R, we can combine vectors of equal length into a data frame using the `data.frame()` function. Here, we're creating two vectors, `name` and `age`, and combining them into a data frame, demonstrating how to organize and structure data in a tabular format. code: | df <- data.frame(name = c('Alice', 'Bob', 'Charlie'), age = c(25, 32, 28)) + check: | + grade_this({ + # The student's solution + df_student <- .result + + # Expected names + expected_names <- c('Alice', 'Bob', 'Charlie') + + # Check that the data frame has the correct structure + has_correct_columns <- all(names(df_student) == c('name', 'age')) + contains_all_names <- all(expected_names %in% df_student$name) + are_ages_numeric <- is.numeric(df_student$age) + + # Provide detailed feedback based on specific issues + if (!has_correct_columns) { + fail("Incorrect columns. Ensure your data frame has exactly two columns named `name` and `age`.") + } else if (!contains_all_names) { + missing_names <- setdiff(expected_names, df_student$name) + fail(paste("Missing the following names:", paste(missing_names, collapse = ", "))) + } else if (!are_ages_numeric) { + fail("The `age` column should contain numeric values only. Ensure all ages are numbers.") + } else { + pass("Correct! You've successfully created a data frame with the names 'Alice', 'Bob', and 'Charlie', and ensured that ages are numeric.") + } + }) - instructions: "Create a numeric vector `nums` with the values 10, 20, and 30 and add 5 to each element of the vector." hints: - "# You can create a vector using the `c()` function."