diff --git a/README.md b/README.md
index 0c361fc..c1ee93c 100644
--- a/README.md
+++ b/README.md
@@ -2,40 +2,32 @@
This series of 10 workshops walks participants through the steps required to use R for a wide array of statistical analyses relevant to research in biology and ecology. These open-access workshops were created by members of the QCBS both for members of the QCBS and the larger community.
-The content of this workshop has been peer-reviewed by several QCBS members. If you would like to suggest modifications, please contact the current series coordinators, listed [here](https://wiki.qcbs.ca/r).
+The content of this workshop has been peer-reviewed by several QCBS members. If you would like to suggest modifications, please contact the current series coordinators, listed [here](https://wiki.qcbs.ca/r) or open a pull request (see contributing guidelines at https://qcbsrworkshops.github.io/guidelines.html).
# [Série d'ateliers R du CSBQ](https://wiki.qcbs.ca/r)
Cette série de 10 ateliers guide les participants à travers les étapes requises afin de maîtriser le logiciel R pour une grande variété d’analyses statistiques pertinentes en recherche en biologie et en écologie. Ces ateliers en libre accès ont été créés par des membres du CSBQ à la fois pour les membres du CSBQ et pour la grande communauté d’utilisateurs de R.
-Le contenu de cet atelier a été révisé par plusieurs membres du CSBQ. Si vous souhaitez y apporter des modifications, veuillez SVP contacter les coordonnateurs actuels de la série, listés [ici](https://wiki.qcbs.ca/r).
+Le contenu de cet atelier a été révisé par plusieurs membres du CSBQ. Si vous souhaitez y apporter des modifications, veuillez SVP contacter les coordonnateurs actuels de la série, listés [ici](https://wiki.qcbs.ca/r)
+ou ouvrez un pull request (voir les instructions https://qcbsrworkshops.github.io/guidelines.html).
-# Workshop 5: Programming in R
-[![Build Status](https://travis-ci.org/QCBSRworkshops/workshop05.svg?branch=dev)](https://travis-ci.org/QCBSRworkshops/workshop05)
+# Workshop 5: Programming in R
+[![Build Status](https://img.shields.io/travis/QCBSRworkshops/workshop05/dev?style=flat-square&logo=travis)](https://travis-ci.org/QCBSRworkshops/workshop05)
+[![badge](https://img.shields.io/static/v1?style=flat-square&label=repo&message=dev&color=6f42c1&logo=github)](https://github.com/QCBSRworkshops/workshop05)
+[![badge](https://img.shields.io/static/v1?style=flat-square&label=wiki&message=05&logo=wikipedia)](https://wiki.qcbs.ca/r_workshop5)
+[![badge](https://img.shields.io/static/v1?style=flat-square&label=Slides&message=05&color=red&logo=html5)](https://qcbsrworkshops.github.io/workshop05/workshop05-en/workshop05-en.html)
+[![badge](https://img.shields.io/static/v1?style=flat-square&label=Slides&message=05&color=red&logo=adobe-acrobat-reader)](https://qcbsrworkshops.github.io/workshop05/workshop05-en/workshop05-en.pdf)
+[![badge](https://img.shields.io/static/v1?style=flat-square&label=script&message=05&color=2a50b8&logo=r)](https://qcbsrworkshops.github.io/workshop05/workshop05-en/workshop05-en.R)
This workshop focuses on basic programming in R. In this workshop, you will learn how to use control flow (`for` loops, `if`, `while`) methods to prevent code repetition, facilitate organization and run simulations. In addition, you will learn to write your own functions, and tips to program efficiently. The last part of the workshop will discuss packages that will not be covered elsewhere in this workshop series, but that may be of interest to participants.
# Atelier 5: Programmation en R
-
-[![Build Status](https://travis-ci.org/QCBSRworkshops/workshop05.svg?branch=dev)](https://travis-ci.org/QCBSRworkshops/workshop05)
+[![Build Status](https://img.shields.io/travis/QCBSRworkshops/workshop05/dev?style=flat-square&logo=travis)](https://travis-ci.org/QCBSRworkshops/workshop05)
+[![badge](https://img.shields.io/static/v1?style=flat-square&label=repo&message=dev&color=6f42c1&logo=github)](https://github.com/QCBSRworkshops/workshop05)
+[![badge](https://img.shields.io/static/v1?style=flat-square&label=wiki&message=05&logo=wikipedia)](https://wiki.qcbs.ca/r_atelier5)
+[![badge](https://img.shields.io/static/v1?style=flat-square&label=Diapos&message=05&color=red&logo=html5)](https://qcbsrworkshops.github.io/workshop05/workshop05-fr/workshop05-fr.html)
+[![badge](https://img.shields.io/static/v1?style=flat-square&label=Diapos&message=05&color=red&logo=adobe-acrobat-reader)](https://qcbsrworkshops.github.io/workshop05/workshop05-fr/workshop05-fr.pdf)
+[![badge](https://img.shields.io/static/v1?style=flat-square&label=script&message=05&color=2a50b8&logo=r)](https://qcbsrworkshops.github.io/workshop05/workshop05-fr/workshop05-fr.R)
Cet atelier vise à vous apprendre les bases de la programmation en R. Vous apprendrez à utiliser des structures de contrôle (boucles `for`, `if`, `while`) afin d'éviter la répétition de code, de faciliter l'organisation et d'effectuer des simulations. Vous apprendrez également à écrire vos propres fonctions et quelques astuces pour programmer plus efficacement. La dernière partie de l'atelier portera sur des librairies de R qui peuvent être très utiles pour les participants, mais qui ne seront pas couvertes ailleurs dans la série d'ateliers en R du CSBQ.
-
-# Links
-
-#### [English](https://qcbsrworkshops.github.io/workshop05/workshop05-en/workshop05-en.html)
-
-#### [Français](https://qcbsrworkshops.github.io/workshop05/workshop05-fr/workshop05-fr.html)
-
-# Developers
-
-1. Set the working directory set to this folder.
-2. then use:
-
-``` r
-install.packages("remotes")
-remotes::install_github("QCBSRworkshops/qcbsRworkshops")
-library("qcbsRworkshops")
-build_workshops()
-```
diff --git a/workshop05-en/qcbsR-fonts.css b/workshop05-en/qcbsR-fonts.css
index 6f8f87f..d04ac62 100644
--- a/workshop05-en/qcbsR-fonts.css
+++ b/workshop05-en/qcbsR-fonts.css
@@ -1,24 +1,17 @@
/* Code font */
-@import url('https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic');
+@import url('https://cdn.jsdelivr.net/gh/tonsky/FiraCode@1.206/distr/fira_code.css');
+@import url('https://fonts.googleapis.com/css?family=Roboto+Slab&display=swap');
/* Title code */
-@import url('https://fonts.googleapis.com/css?family=Anton|Bevan|Black+Han+Sans|Luckiest+Guy|Bowlby+One|Lalezar');
/* Body */
-@import url('https://fonts.googleapis.com/css?family=Arya');
-
+/* Fira Sans */
+@import url('https://fonts.googleapis.com/css?family=Fira+Sans:200,200i 300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i&display=swap');
body {
- font-family: 'Arya';
-}
-
-h1 {
- font-family: 'Lalezar', cursive;
- font-weight: 400;
-}
-
-.maintitle {
- font-family: 'Lalezar', cursive;
+ font-family: 'Fira Sans', sans-serif;
+ font-weight: 300;
+ line-height: 1.2;
}
.remark-code, .remark-inline-code {
- font-family: 'Ubuntu Mono';
-}
+ font-family: "Fira Code", monospace;
+}
\ No newline at end of file
diff --git a/workshop05-en/qcbsR-macros.js b/workshop05-en/qcbsR-macros.js
index b8f52e9..6ba4cb4 100644
--- a/workshop05-en/qcbsR-macros.js
+++ b/workshop05-en/qcbsR-macros.js
@@ -4,13 +4,12 @@ remark.macros.scale = function (percentage) {
return '';
};
-// Image top right
+// Rubik's cube image => top right
remark.macros.cube = function () {
var url = "images/rubicub.png";
- return '';
+ return '';
};
-
// Font-awesome icons (versio 4.7)
remark.macros.faic = function (size = 2) {
var name = this;
@@ -23,9 +22,10 @@ remark.macros.acic = function (size = 2) {
return '';
};
-
// toupper (see https://github.com/gnab/remark/issues/72)
remark.macros.upper = function () {
// `this` is the value in the parenthesis, or undefined if left out
return this.toUpperCase();
};
+
+
diff --git a/workshop05-en/qcbsR.css b/workshop05-en/qcbsR.css
index 462d711..768e0d7 100644
--- a/workshop05-en/qcbsR.css
+++ b/workshop05-en/qcbsR.css
@@ -1,84 +1,147 @@
-.remark-code-line-highlighted {
- background-color: #ffdd55;
+html {
+ margin: 0px;
+ padding: 0px;
}
.remark-slide-content {
- border-right: 5px solid #303940;
- border-left: 5px solid #303940;
- padding: .2em;
- margin: .15em;
- font-size: 24px;
- color: #32454f;
+ padding: 0px;
+ color: #062c45;
}
-.remark-slide-number {
- font-size: 12pt;
- margin-bottom: -11.6px;
- margin-right: 10px;
- color: #374559;
- opacity: 0.6; /* default: 0.5 */
+
+.remark-slide-content p {
+ font-size: 1.5rem;
+ padding: .4rem 1rem .4rem 1.4rem;
+ margin: .1rem;
}
+.maintitle {
+ font-family: 'Roboto Slab';
+ font-weight: normal;
+}
-.remark-slide-content p, .remark-slide-content ul, .remark-slide-content ol {
- margin: .2em 1em;
+.remark-code-line {
+ font-size: 1.25rem;
+ line-height: 1.4;
}
- /* Header */
-.remark-slide-content h1 {
- font-size: 48px;
- border-bottom: 3px solid;
- margin: 0em .5em;
+.hljs {
+ padding: .8rem 1rem .8rem 1rem !important;
+ background-color: #f3f3f3 !important;
}
-.remark-slide-content h2 {
- font-size: 46px;
- margin: 0em .5em;
+.remark-code .remark-code-line {
+ padding-left: 1rem !important;
}
-.remark-slide-content h3 {
- font-size: 42px;
- margin: 0em .6em;
+.remark-inline-code {
+ background-color: #f3f3f3;
+ border-radius: 5px;
+ border: 1px solid #999;
+ padding: 1px !important;
+ font-size: 80%;
}
-.remark-slide-content h4 {
- font-size: 36px;
- margin: 0em .7em;
+h1 .remark-inline-code {
+ background-color: #999;
+ border: 1px solid #f3f3f3;
}
-.remark-slide-content h5 {
- font-size: 32px;
- margin: 0em .8em;
+.remark-code-line-highlighted {
+ background-color: #fcd3f2;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
}
+pre {
+ margin: .4rem 0rem;
+}
+hr {
+ color: #fcd3f2;
+ width: 80%
+}
+
+.remark-slide-content h1 {
+ font-weight: 500;
+ padding: .4em .4rem .8rem 1.2rem;
+ margin: 0rem;
+ margin-bottom: .8rem;
+ font-size: 2.4rem;
+ background-color: #062c45;
+ color: #f3f3f3;
+}
+.remark-slide-content h2 {
+ font-weight: 500;
+ padding: .6em .4rem .8rem 1.2rem;
+ margin: 0rem;
+ margin-bottom: .8rem;
+ font-size: 2.4rem;
+}
+.remark-slide-content h3 {
+ font-weight: 500;
+ padding: .6rem .4rem .6rem 1.4rem;
+ margin: .2rem;
+ font-size: 2.2rem;
+}
+.remark-slide-content h4 {
+ font-weight: 400;
+ padding: .6rem .4rem .6rem 1.4rem;
+ margin: .2rem;
+ font-size: 2rem;
+}
+.remark-slide-content h5 {
+ font-weight: 400;
+ padding: .5rem .4rem .5rem 1.6rem;
+ margin: .2rem;
+ font-size: 1.8rem;
+}
.remark-slide-content h6 {
- font-size: 28px;
- margin: 0em .9em;
+ font-weight: 400;
+ padding: .4rem .4rem .4rem 1.6rem;
+ margin: .2rem;
+ font-size: 1.7rem;
}
-/* Code */
-a, a > code {
- color: #3fb3b2;
- font-weight: bold;
- text-decoration: none;
+
+
+.remark-slide-number {
+ font-size: 12pt;
+ margin-bottom: -11.6px;
+ margin-right: 8px;
+ color: #062c45;
+ opacity: 0.6; /* default: 0.5 */
+ font-weight: 400;
}
-.remark-code {
- color: #303940;
- background-color: #f3f3f3;
- font-size: 85%;
+
+.remark-slide-content li {
+ margin: .4rem 2rem;
+ padding-left: .2rem;
+ font-size: 1.5rem;
}
-.remark-inline-code {
- color: #303940;
- background-color: #f3f3f3;
- font-size: 90%;
+.remark-slide-content ul, .remark-slide-content ol {
+ margin: .4rem .1rem;
+ padding-left: .4rem;
+ font-size: 1.5rem;
}
-.remark-code-line, p {
- margin: .2em .2em;
+
+/* links */
+a {
+ color: #309493;
+ font-weight: 400;
+}
+a > code {
+ color: #309493;
}
+a:hover {
+ font-weight: 700;
+ text-decoration-style: underline;
+}
+
/* MathJax */
.mjx-chtml{ font-size: 100% !important; }
@@ -86,29 +149,41 @@ a, a > code {
/* special text */
.alert {
- color: #c7254e;
+ color: #c11534;
font-weight: bold;
}
.comment {
- color: #645193;
+ color: #666;
+ font-style: italic;
}
.huge {
- font-size: 2em;
+ font-size: 1.6em;
+ font-weight: 500;
+}
+
+.xlarge {
+ font-size: 1.25em;
+ font-weight: 400;
}
.large {
- font-size: 1.5em;
+ font-size: 1.1em;
}
.small {
font-size: .9em;
}
+.xsmall {
+ font-size: .75em;
+}
+
.tiny {
font-size: .6em;
+ font-weight: 200;
}
.footnote {
@@ -118,6 +193,21 @@ a, a > code {
font-size: 60%;
}
+/* help style */
+
+.remark-help-content h1 {
+ color: #fff;
+}
+
+.remark-help {
+ color: #fff;
+}
+
+.remark-help tr:nth-child(even) {
+ background-color: #999;
+}
+
+
/* Column */
.pull-left {
@@ -138,6 +228,10 @@ a, a > code {
width: 27%;
}
+.pull-right2, .pull-right2 p {
+ padding-left: 0rem ;
+}
+
/* Blockquote */
.remark-slide-content blockquote {
font-size: 1em;
@@ -150,14 +244,24 @@ a, a > code {
.inverse {
border-left: 5px solid #f3f3f3;
border-right: 5px solid #f3f3f3;
- background-color: #32454f;
+ background-color: #062c45;
color: #f3f3f3;
}
.inverse h1, .inverse h2, .inverse h3 {
color: #f3f3f3;
+ background-color: transparent;
}
+.inverse h1 {
+ font-size: 2.8rem;
+}
+.inverse h2 {
+ font-size: 2.4rem;
+}
+.inverse h3 {
+ font-size: 2rem;
+}
/* Table */
@@ -190,7 +294,7 @@ table, td, th {
/* for title page with logo and QCBS background */
.maintitle {
font-size: 3em;
- color: #334853;
+ color: #062c45;
text-align: center;
}
@@ -199,7 +303,6 @@ table, td, th {
background-size: cover;
}
-
.title-slide:before{
position: absolute;
top: -35%;
@@ -207,20 +310,3 @@ table, td, th {
content: url(https://qcbs.ca/wp-content/uploads/2010/05/logo_small_grey-01.png);
transform: scale(.25);
}
-
-
-
-
-/* help style */
-
-.remark-help-content h1 {
- color: #fff;
-}
-
-.remark-help {
- color: #fff;
-}
-
-.remark-help tr:nth-child(even) {
- background-color: #999;
-}
diff --git a/workshop05-en/workshop05-en.R b/workshop05-en/workshop05-en.R
new file mode 100644
index 0000000..f55d42a
--- /dev/null
+++ b/workshop05-en/workshop05-en.R
@@ -0,0 +1,506 @@
+## ----setup, echo = FALSE------------------------------------------------------
+knitr::opts_chunk$set(
+ comment = "#",
+ collapse = TRUE,
+ warning = FALSE,
+ message = FALSE,
+ fig.width=6, fig.height=6,
+ fig.retina = 3,
+ fig.align = 'center'
+)
+options(repos=structure(c(CRAN="http://cran.r-project.org")))
+
+
+## ----echo = FALSE, results = "asis"-------------------------------------------
+bge <- qcbsRworkshops::get_badges(5, style = "for-the-badge", clip = FALSE,
+show = FALSE)
+cat(bge[-1L])
+
+
+## -----------------------------------------------------------------------------
+ num.vector <- c(1, 4, 3, 98, 32, -76, -4)
+
+## -----------------------------------------------------------------------------
+ num.vector
+
+
+## -----------------------------------------------------------------------------
+ siteID <- c("A1.01", "A1.02", "B1.01", "B1.02")
+ soil_pH <- c(5.6, 7.3, 4.1, 6.0)
+ num.sp <- c(17, 23, 15, 7)
+ treatment <- c("Fert", "Fert", "No_fert", "No_fert")
+
+
+## -----------------------------------------------------------------------------
+ my.first.df <- data.frame(siteID, soil_pH, num.sp, treatment)
+
+## -----------------------------------------------------------------------------
+ my.first.df
+
+
+## -----------------------------------------------------------------------------
+ my.first.list <- list(siteID, soil_pH, num.sp, treatment)
+
+
+## -----------------------------------------------------------------------------
+ my.first.list
+
+
+## -----------------------------------------------------------------------------
+Paws <- "cat"
+Scruffy <- "dog"
+Sassy <- "cat"
+animals <- c(Paws, Scruffy, Sassy)
+
+
+## -----------------------------------------------------------------------------
+if(Paws == 'cat') {
+ print("meow")
+}
+
+
+## -----------------------------------------------------------------------------
+x = Paws
+# x = Scruffy
+if(x == 'cat') {
+ print("meow")
+} else {
+ print("woof")
+}
+
+
+## -----------------------------------------------------------------------------
+animals <- c(Paws, Scruffy, Sassy)
+
+ifelse(animals == 'dog', "woof", "meow")
+
+
+## -----------------------------------------------------------------------------
+for(val in 1:3) {
+ if(animals[val] == 'cat') {
+ print("meow")
+ }else if(animals[val] == 'dog') {
+ print("woof")
+ }else print("what?")
+}
+
+
+## -----------------------------------------------------------------------------
+if (2+2 == 4) { #<<
+ print("Arithmetic works.")
+} else { #<<
+ print("Houston, we have a problem.")
+} #<<
+
+
+## ----echo=FALSE---------------------------------------------------------------
+for(m in 1:5) {
+ print(m*2)
+}
+
+
+## ----echo=FALSE---------------------------------------------------------------
+for(m in 6:10) {
+ print(m*2)
+}
+
+
+## ----echo = FALSE-------------------------------------------------------------
+for (i in 4:5) { # for i in 4 to 5
+ print(colnames(CO2)[i])
+ print(mean(CO2[,i])) # print the mean of that column from the CO2 dataset
+}
+
+
+## ----echo = -c(2:5)-----------------------------------------------------------
+# Output
+
+for (i in 1:3) {
+ for (n in 1:3) {
+ print (i*n)
+ }
+}
+
+
+## -----------------------------------------------------------------------------
+(height <- matrix(c(1:10, 21:30),
+ nrow = 5,
+ ncol = 4))
+
+
+
+## -----------------------------------------------------------------------------
+apply(X = height,
+ MARGIN = 1,
+ FUN = mean)
+
+
+
+## ----eval = FALSE-------------------------------------------------------------
+## SimulatedData <- list(
+## SimpleSequence = 1:4,
+## Norm10 = rnorm(10),
+## Norm20 = rnorm(20, 1),
+## Norm100 = rnorm(100, 5))
+##
+## # Apply mean to each element
+## ## of the list
+## lapply(SimulatedData, mean)
+
+
+## ----echo=FALSE---------------------------------------------------------------
+SimulatedData <- list(SimpleSequence = 1:4,
+ Norm10 = rnorm(10),
+ Norm20 = rnorm(20, 1),
+ Norm100 = rnorm(100, 5))
+
+# Apply mean to each element of the list
+lapply(SimulatedData, mean)
+
+
+## ----eval = TRUE--------------------------------------------------------------
+SimulatedData <- list(SimpleSequence = 1:4,
+ Norm10 = rnorm(10),
+ Norm20 = rnorm(20, 1),
+ Norm100 = rnorm(100, 5))
+
+## -----------------------------------------------------------------------------
+# Apply mean to each element of the list
+sapply(SimulatedData, mean)
+
+
+## -----------------------------------------------------------------------------
+lilySeeds <- c(80, 65, 89, 23, 21)
+poppySeeds <- c(20, 35, 11, 77, 79)
+
+## -----------------------------------------------------------------------------
+# Output
+mapply(sum, lilySeeds, poppySeeds)
+
+
+## -----------------------------------------------------------------------------
+head(mtcars)
+
+## -----------------------------------------------------------------------------
+# get the mean hp by cylinder groups
+tapply(mtcars$hp, mtcars$cyl, FUN = mean)
+
+
+## ----echo=TRUE----------------------------------------------------------------
+for (i in 1:dim(CO2)[1]) {
+ if(CO2$Type[i] == "Quebec") {
+ CO2$uptake[i] <- CO2$uptake[i] - 2
+ }
+}
+
+
+## ----echo=TRUE----------------------------------------------------------------
+tapply(CO2$uptake, CO2$Type, mean)
+
+
+## ----eval = FALSE-------------------------------------------------------------
+## count <- 0
+##
+## for (i in 1:nrow(CO2)) {
+## if (CO2$Treatment[i] == "nonchilled") next
+## # Skip to next iteration if treatment is nonchilled
+## count <- count + 1
+## # print(CO2$conc[i])
+## }
+## print(count) # The count and print command were performed 42 times.
+
+
+## ----echo = FALSE-------------------------------------------------------------
+count <- 0
+
+for (i in 1:nrow(CO2)) {
+ if (CO2$Treatment[i] == "nonchilled") next
+ # Skip to next iteration if treatment is nonchilled
+ count <- count + 1
+}
+print(count) # The count and print command were performed 42 times.
+
+
+## -----------------------------------------------------------------------------
+sum(CO2$Treatment == "nonchilled")
+
+
+## ----eval = FALSE-------------------------------------------------------------
+## count <- 0
+## i <- 0
+## repeat {
+## i <- i + 1
+## if (CO2$Treatment[i] == "nonchilled") next # skip this loop
+## count <- count + 1
+## print(CO2$conc[i])
+## if (i == nrow(CO2)) break # stop looping
+## }
+## print(count)
+
+
+## ----eval = FALSE-------------------------------------------------------------
+## i <- 0
+## count <- 0
+## while (i < nrow(CO2))
+## {
+## i <- i + 1
+## if (CO2$Treatment[i] == "nonchilled") next # skip this loop
+## count <- count + 1
+## print(CO2$conc[i])
+## }
+## print(count)
+
+
+## -----------------------------------------------------------------------------
+data(CO2)
+
+
+## -----------------------------------------------------------------------------
+for (i in 1:nrow(CO2)) {
+ if(CO2$Type[i] == "Mississippi") {
+ if(CO2$conc[i] < 300) next
+ CO2$conc[i] <- CO2$conc[i] - 20
+ }
+}
+
+
+## -----------------------------------------------------------------------------
+for (i in 1:nrow(CO2)) {
+ if(CO2$Type[i] == "Mississippi" && CO2$conc[i] >= 300) {
+ CO2$conc[i] <- CO2$conc[i] - 20
+ }
+}
+
+
+## ---- eval=F------------------------------------------------------------------
+## plot(x = CO2$conc, y = CO2$uptake, type = "n", cex.lab=1.4,
+## xlab = "CO2 concentration", ylab = "CO2 uptake")
+## # Type "n" tells R to not actually plot the points.
+## for (i in 1:length(CO2[,1])) {
+## if (CO2$Type[i] == "Quebec" & CO2$Treatment[i] == "nonchilled") {
+## points(CO2$conc[i], CO2$uptake[i], col = "red")
+## }
+## if (CO2$Type[i] == "Quebec" & CO2$Treatment[i] == "chilled") {
+## points(CO2$conc[i], CO2$uptake[i], col = "blue")
+## }
+## if (CO2$Type[i] == "Mississippi" & CO2$Treatment[i] == "nonchilled") {
+## points(CO2$conc[i], CO2$uptake[i], col = "orange")
+## }
+## if (CO2$Type[i] == "Mississippi" & CO2$Treatment[i] == "chilled") {
+## points(CO2$conc[i], CO2$uptake[i], col = "green")
+## }
+## }
+
+
+## ---- eval = TRUE, echo = FALSE, fig.height=6, fig.width=7--------------------
+plot(x=CO2$conc, y=CO2$uptake, type="n", cex.lab=1.4, xlab="CO2 Concentration", ylab="CO2 Uptake") # Type "n" tells R to not actually plot the points.
+
+for (i in 1:length(CO2[,1])) {
+ if (CO2$Type[i] == "Quebec" & CO2$Treatment[i] == "nonchilled") {
+ points(CO2$conc[i], CO2$uptake[i], col = "red")
+ }
+ if (CO2$Type[i] == "Quebec" & CO2$Treatment[i] == "chilled") {
+ points(CO2$conc[i], CO2$uptake[i], col = "blue")
+ }
+ if (CO2$Type[i] == "Mississippi" & CO2$Treatment[i] == "nonchilled") {
+ points(CO2$conc[i], CO2$uptake[i], col = "orange")
+ }
+ if (CO2$Type[i] == "Mississippi" & CO2$Treatment[i] == "chilled") {
+ points(CO2$conc[i], CO2$uptake[i], col = "green")
+ }
+}
+
+
+## ---- echo = -1, fig.height=4-------------------------------------------------
+par(mar = c(4, 4.1, 0.5, 0.5))
+plot(x = CO2$conc, y = CO2$uptake, type = "n", cex.lab=1.4,
+ xlab = "CO2 concentration", ylab = "CO2 uptake")
+
+plants <- unique(CO2$Plant)
+
+for (i in 1:nrow(CO2)){
+ for (p in 1:length(plants)) {
+ if (CO2$Plant[i] == plants[p]) {
+ points(CO2$conc[i], CO2$uptake[i], col = p)
+}}}
+
+
+## -----------------------------------------------------------------------------
+operations <- function(number1, number2, number3) {
+ result <- (number1 + number2) * number3
+ print(result)
+}
+
+## -----------------------------------------------------------------------------
+operations(1, 2, 3)
+
+
+## ---- echo=F------------------------------------------------------------------
+print_animal <- function(animal) {
+ if (animal == "dog") {
+ print("woof")
+ } else if (animal == "cat") {
+ print("meow")
+ }
+}
+
+
+## -----------------------------------------------------------------------------
+Scruffy <- "dog"
+Paws <- "cat"
+
+print_animal(Scruffy)
+
+print_animal(Paws)
+
+
+## -----------------------------------------------------------------------------
+operations <- function(number1, number2, number3 = 3) {
+ result <- (number1 + number2) * number3
+ print(result)
+}
+
+operations(1, 2, 3) # is equivalent to
+operations(1, 2)
+operations(1, 2, 2) # we can still change the value of number3 if needed
+
+
+## ---- eval = FALSE------------------------------------------------------------
+## plot.CO2 <- function(CO2, ...) {
+## plot(x=CO2$conc, y=CO2$uptake, type="n", ...) #<<
+## for (i in 1:length(CO2[,1])){
+## if (CO2$Type[i] == "Quebec") {
+## points(CO2$conc[i], CO2$uptake[i], col = "red", type = "p", ...) #<<
+## } else if (CO2$Type[i] == "Mississippi") {
+## points(CO2$conc[i], CO2$uptake[i], col = "blue", type = "p", ...) #<<
+## }
+## }
+## }
+## plot.CO2(CO2, cex.lab=1.2, xlab="CO2 concentration", ylab="CO2 uptake")
+## plot.CO2(CO2, cex.lab=1.2, xlab="CO2 concentration", ylab="CO2 uptake", pch=20)
+
+
+## ---- echo=F, fig.height=4.5, fig.width=10------------------------------------
+plot.CO2 <- function(CO2, ...) {
+ plot(x = CO2$conc, y = CO2$uptake, type = "n", ...)
+
+ for (i in 1:length(CO2[,1])){
+ if (CO2$Type[i] == "Quebec") {
+ points(CO2$conc[i], CO2$uptake[i], col="red", type="p", ...)
+ } else if (CO2$Type[i] == "Mississippi") {
+ points(CO2$conc[i], CO2$uptake[i], col="blue", type="p", ...)
+ }
+ }
+}
+par(mfrow=c(1,2), mar = c(4,4,1,1))
+plot.CO2(CO2, cex.lab=1.2, xlab="CO2 concentration", ylab="CO2 uptake")
+plot.CO2(CO2, cex.lab=1.2, xlab="CO2 concentration", ylab="CO2 uptake", pch=20)
+
+
+## -----------------------------------------------------------------------------
+sum2 <- function(...){
+ args <- list(...) #<<
+ result <- 0
+ for (i in args) {
+ result <- result + i
+ }
+ return (result)
+}
+
+sum2(2, 3)
+sum2(2, 4, 5, 7688, 1)
+
+
+## -----------------------------------------------------------------------------
+myfun <- function(x) {
+ if (x < 10) {
+ 0
+ } else {
+ 10
+ }
+}
+
+myfun(5)
+myfun(15)
+
+
+## -----------------------------------------------------------------------------
+simplefun1 <- function(x) {
+ if (x<0)
+ return(x)
+}
+
+
+## ----echo = TRUE--------------------------------------------------------------
+simplefun2 <- function(x, y) {
+ z <- x + y
+ return(list("result" = z,
+ "x" = x,
+ "y" = y))
+}
+
+
+## ---- eval = FALSE------------------------------------------------------------
+## simplefun2(1, 2)
+
+
+## ---- echo = FALSE------------------------------------------------------------
+simplefun2(1, 2)
+
+
+## ---- error = TRUE------------------------------------------------------------
+var1 <- 3 # var1 is defined outside our function
+vartest <- function() {
+ a <- 4 # 'a' is defined inside
+ print(a) # print 'a'
+ print(var1) # print var1
+}
+
+a # we cannot print 'a' as it exists only inside the function
+
+vartest() # calling vartest() will print a and var1
+
+rm(var1) # remove var1
+vartest() # calling the function again doesn't work anymore
+
+
+## -----------------------------------------------------------------------------
+var1 <- 3 # var1 is defined outside our function
+vartest <- function(var1) {
+ print(var1) # print var1
+}
+
+vartest(8) # Inside our function var1 is now our argument and takes its value
+
+var1 # var1 still has the same value
+
+
+## ----eval = FALSE-------------------------------------------------------------
+## a <- 3
+## if (a > 5) {
+## b <- 2
+## }
+##
+## a + b
+
+
+## ----eval = FALSE-------------------------------------------------------------
+## # Error: object 'b' not found
+
+
+## ----eval = FALSE-------------------------------------------------------------
+## recalibrate <- function(CO2, type, bias){
+## for (i in 1:nrow(CO2)) {
+## if(CO2$Type[i] == type) {
+## CO2$conc[i] <- CO2$conc[i] + bias
+## }
+## }
+## return(CO2)
+## }
+##
+
+
+## ----eval = FALSE-------------------------------------------------------------
+## newCO2 <- recalibrate(CO2, "Mississipi", -20)
+## newCO2 <- recalibrate(newCO2, "Quebec", +50)
+
diff --git a/workshop05-en/workshop05-en.Rmd b/workshop05-en/workshop05-en.Rmd
index 52a9efe..82e1331 100644
--- a/workshop05-en/workshop05-en.Rmd
+++ b/workshop05-en/workshop05-en.Rmd
@@ -15,7 +15,7 @@ output:
---
-```{r setup, echo = F}
+```{r setup, echo = FALSE}
knitr::opts_chunk$set(
comment = "#",
collapse = TRUE,
@@ -25,14 +25,26 @@ knitr::opts_chunk$set(
fig.retina = 3,
fig.align = 'center'
)
+options(repos=structure(c(CRAN="http://cran.r-project.org")))
```
-## Outline
+class: inverse, center, middle
+
+# About this workshop
-1. Learning what is **control flow**
-2. Writing your first functions in R
-3. Speeding up your code
-4. Useful R packages for biologists
+```{R echo = FALSE, results = "asis"}
+bge <- qcbsRworkshops::get_badges(5, style = "for-the-badge", clip = FALSE,
+show = FALSE)
+cat(bge[-1L])
+```
+
+---
+# Outline
+
+##### 1. Learning what is **control flow**
+##### 2. Writing your first functions in R
+##### 3. Speeding up your code
+##### 4. Useful R packages for biologists
---
class: inverse, center, middle
@@ -40,12 +52,12 @@ class: inverse, center, middle
# Review
---
-## Objects
+# Objects
-![](images/matrix.png)
+![:scale 90%](images/matrix.png)
---
-## Vectors
+# Vectors
Numeric vectors
@@ -57,7 +69,7 @@ Numeric vectors
```
---
-## Data frames
+# Data frames
vectors
@@ -78,7 +90,7 @@ We then combine them using the function `data.frame`
```
---
-## Lists
+# Lists
```{r}
my.first.list <- list(siteID, soil_pH, num.sp, treatment)
@@ -94,7 +106,7 @@ class: inverse, center, middle
# Control flow
---
-## Control flow
+# Control flow
Program flow control can be simply defined as the order in which a program is executed.
@@ -107,7 +119,7 @@ Program flow control can be simply defined as the order in which a program is ex
.large[.center[**This means increased productivity**]]
---
-## Control flow
+# Control flow
Flowcharts can be used to plan programs and represent their structure
@@ -116,7 +128,7 @@ Flowcharts can be used to plan programs and represent their structure
![](images/flowchart1.png)
---
-## Representing structure
+# Representing structure
The two basic building blocks of codes are the following:
@@ -147,7 +159,7 @@ repeat
]
---
-## Decision making
+# Decision making
.pull-left[
@@ -180,7 +192,7 @@ if(condition) {
]
---
-#### What if you want to test more than one condition?
+### What if you want to test more than one condition?
- `if` and `if` `else` test a single condition
- You can also use `ifelse` function to:
@@ -196,7 +208,7 @@ sqrt(ifelse(a >= 0, a, NA))
```
---
-## Nested `if` `else` statement
+# Nested `if` `else` statement
.small[
```r
@@ -213,10 +225,10 @@ statement4
]
.center[
-![:scale 68%](images/nested_ifelse.png)]
+![:scale 60%](images/nested_ifelse.png)]
---
-## Challenge 1 ![:cube]()
+# Challenge 1 ![:cube]()
```{r}
Paws <- "cat"
@@ -230,7 +242,7 @@ animals <- c(Paws, Scruffy, Sassy)
3. Use the `ifelse` function to display `“woof”` for `animals` that are dogs and `“meow”` for `animals` that are cats.
---
-## Challenge 1 - Solution ![:cube]()
+# Challenge 1 - Solution ![:cube]()
1- Use an `if` statement to print “meow” if `Paws` is a “cat”.
@@ -253,7 +265,7 @@ if(x == 'cat') {
```
---
-## Challenge 1 - Solution ![:cube]()
+# Challenge 1 - Solution ![:cube]()
3- Use the `ifelse` function to display `“woof”` for `animals` that are dogs and `“meow”` for `animals` that are cats.
@@ -276,7 +288,7 @@ for(val in 1:3) {
```
---
-## Beware of R’s expression parsing!
+# Beware of R’s expression parsing!
Use curly brackets `{}` so that R knows to expect more input. Try:
@@ -297,7 +309,8 @@ if (2+2 == 4) { #<<
} #<<
```
---
-## Remember the logical operators
+# Remember the logical operators
+
| Command | Meaning |
| :-------------: | :-------------: |
@@ -313,7 +326,7 @@ if (2+2 == 4) { #<<
---
-## Iteration
+# Iteration
Every time some operations have to be repeated, a loop may come in handy
@@ -325,7 +338,7 @@ Loops are good for:
- iterating a calculation until it converges
---
-## `for` loop
+# `for` loop
A `for` loop works in the following way:
@@ -340,7 +353,7 @@ for(val in sequence) {
]
---
-## `for` loop
+# `for` loop
The letter `i` can be replaced with any variable name and the sequence can be almost anything, even a list of vectors.
```r
@@ -362,7 +375,7 @@ for (element in elements) {
```
---
-## `for` loop
+# `for` loop
In the example below, R would evaluate the expression 5 times:
@@ -399,7 +412,7 @@ for(m in 6:10) {
]
]
---
-## `for` loop
+# `for` loop
.small[
```r
@@ -415,12 +428,12 @@ print(count)
]
.center[
-![:scale 60%](images/forexample.png)
+![:scale 50%](images/forexample.png)
]
---
-## `for` loop
+# `for` loop
For loops are often used to loop over a dataset. We will use loops to perform functions on the `CO2` dataset which is built in R.
@@ -439,7 +452,7 @@ for (i in 1:length(CO2[,1])) { # for each row in the CO2 dataset
```
---
-## `for` loop
+# `for` loop
.alert[Tip 1]. To loop over the number of rows of a data frame, we can use the function `nrow()`
@@ -458,7 +471,7 @@ for (p in CO2$conc) { # for each element of the column "conc" of the CO2 df
```
---
-## `for` loop
+# `for` loop
The expression within the loop can be almost anything and is usually a compound statement containing many commands.
@@ -477,7 +490,7 @@ for (i in 4:5) { # for i in 4 to 5
}
```
---
-## `for` loops within `for` loops
+# `for` loops within `for` loops
In some cases, you may want to use nested loops to accomplish a task. When using nested loops, it is important to use different variables as counters for each of your loops. Here we used `i` and `n`:
.pull-left[
@@ -502,7 +515,7 @@ for (i in 1:3) {
]
---
-## Getting good: using the `apply()` family
+# Getting good: using the `apply()` family
R disposes of the `apply()` function family, which consists of vectorized functions that aim at **minimizing your need to explicitly create loops**.
@@ -529,7 +542,7 @@ apply(X = height,
]
---
-## `lapply()`
+# `lapply()`
`lapply()` applies a function to every element of a `list`.
@@ -565,7 +578,7 @@ lapply(SimulatedData, mean)
]
---
-## `sapply()`
+# `sapply()`
`sapply()` sapply() is a ‘wrapper’ function for `lapply()`, but returns a simplified output as a `vector`, instead of a `list`.
@@ -586,7 +599,7 @@ sapply(SimulatedData, mean)
]
---
-## `mapply()`
+# `mapply()`
`mapply()` works as a multivariate version of `sapply()`.
@@ -603,7 +616,7 @@ mapply(sum, lilySeeds, poppySeeds)
```
---
-## `tapply()`
+# `tapply()`
`tapply()` is used to apply a function over subsets of a vector.
@@ -618,7 +631,7 @@ tapply(mtcars$hp, mtcars$cyl, FUN = mean)
```
---
-## Challenge 2 ![:cube]()
+# Challenge 2 ![:cube]()
You have realized that your tool for measuring uptake was not calibrated properly at Quebec sites and all measurements are 2 units higher than they should be.
@@ -629,8 +642,7 @@ You have realized that your tool for measuring uptake was not calibrated properl
For this, you will have to load the CO2 dataset using `data(CO2)`, and then use the object `CO2`.
---
-
-## Challenge 2: Solution ![:cube]()
+# Challenge 2: Solution ![:cube]()
1. Using `for` and `if` to correct the measurements:
@@ -647,8 +659,7 @@ for (i in 1:dim(CO2)[1]) {
tapply(CO2$uptake, CO2$Type, mean)
```
---
-
-## Modifying iterations
+# Modifying iterations
Normally, loops iterate over and over until they finish.
@@ -661,7 +672,7 @@ You may also want R to jump certain elements when certain conditions are met.
For this, we will introduce `break`, `next` and `while`.
---
-## Modifying iterations: `break`
+# Modifying iterations: `break`
```r
for(val in x) {
@@ -673,7 +684,7 @@ for(val in x) {
![](images/break.png)
---
-## Modifying iterations: `next`
+# Modifying iterations: `next`
```r
for(val in x) {
@@ -685,7 +696,7 @@ for(val in x) {
![](images/next.png)
---
-## Modifying iterations: `next`
+# Modifying iterations: `next`
Print the $CO_{2}$ concentrations for "chilled" treatments and keep count of how many replications were done.
@@ -717,7 +728,7 @@ sum(CO2$Treatment == "nonchilled")
```
---
-## Modifying iterations: `break`
+# Modifying iterations: `break`
This could be equivalently written using a `repeat` loop and `break`:
@@ -735,7 +746,7 @@ print(count)
```
---
-## Modifying iterations: `while`
+# Modifying iterations: `while`
This could also be written using a `while` loop:
@@ -753,7 +764,7 @@ print(count)
```
---
-## Challenge 3 ![:cube]()
+# Challenge 3 ![:cube]()
You have realized that your tool for measuring concentration did not work properly.
@@ -769,7 +780,7 @@ data(CO2)
---
-## Challenge 3: Solution ![:cube]()
+# Challenge 3: Solution ![:cube]()
```{r}
for (i in 1:nrow(CO2)) {
@@ -789,7 +800,7 @@ for (i in 1:nrow(CO2)) {
```
---
-## Edit a plot using `for` and `if`
+# Edit a plot using `for` and `if`
Let's plot **uptake** vs **concentration** with points of different colors according to their type (*Quebec* or *Mississippi*) and **treatment** (*chilled* or *nonchilled*).
@@ -816,7 +827,7 @@ for (i in 1:length(CO2[,1])) {
]
---
-## Challenge 4 ![:cube]()
+# Challenge 4 ![:cube]()
Create a plot using `for` loop and `if`
@@ -841,7 +852,7 @@ for (i in 1:length(CO2[,1])) {
```
---
-## Challenge 4![:cube]()
+# Challenge 4![:cube]()
@@ -855,7 +866,7 @@ Generate a plot showing **concentration versus uptake** where each plant is show
3. Fill the plot using `for` and `if` statements]
---
-## Challenge 4: Solution ![:cube]()
+# Challenge 4: Solution ![:cube]()
.small[
```{r, echo = -1, fig.height=4}
@@ -879,7 +890,7 @@ class: inverse, center, middle
# Writing functions
---
-## Why write functions?
+# Why write functions?
Much of the heavy lifting in R is done by functions. They are useful for:
@@ -891,7 +902,7 @@ Much of the heavy lifting in R is done by functions. They are useful for:
6. Modifying R’s built-in functionality.
---
-## What is a function?
+# What is a function?
@@ -901,7 +912,7 @@ Much of the heavy lifting in R is done by functions. They are useful for:
---
-## Syntax of a function
+# Syntax of a function
```r
function_name <- function(argument1, argument2, ...) {
@@ -911,7 +922,7 @@ function_name <- function(argument1, argument2, ...) {
```
---
-## Arguments of a function
+# Arguments of a function
```r
function_name <- function(argument1, argument2, ...) {
@@ -935,7 +946,7 @@ operations(1, 2, 3)
```
]
---
-## Challenge 5 ![:cube]()
+# Challenge 5 ![:cube]()
Using what you learned previously on flow control, create a function `print_animal` that takes an `animal` as argument and gives the following results:
@@ -960,7 +971,7 @@ print_animal(Paws)
---
-## Challenge 5: Solution ![:cube]()
+# Challenge 5: Solution ![:cube]()
@@ -975,7 +986,7 @@ print_animal <- function(animal) {
```
---
-## Default values in a function
+# Default values in a function
Arguments can also be optional and be provided with a default value.
@@ -993,7 +1004,7 @@ operations(1, 2, 2) # we can still change the value of number3 if needed
```
---
-## Argument `...`
+# Argument `...`
The special argument `...` allows you to pass on arguments to another function used inside your function. Here we use `...` to pass on arguments to `plot()` and `points()`.
@@ -1014,7 +1025,7 @@ plot.CO2(CO2, cex.lab=1.2, xlab="CO2 concentration", ylab="CO2 uptake", pch=20)
---
-## Argument `...`
+# Argument `...`
The special argument `...` allows you to pass on arguments to another function used inside your function. Here we use `...` to pass on arguments to `plot()` and `points()`.
@@ -1036,7 +1047,7 @@ plot.CO2(CO2, cex.lab=1.2, xlab="CO2 concentration", ylab="CO2 uptake", pch=20)
```
---
-## Argument `...`
+# Argument `...`
The special argument `...` allows you to input an indefinite number of arguments.
@@ -1055,7 +1066,7 @@ sum2(2, 4, 5, 7688, 1)
```
---
-## Return values
+# Return values
The last expression evaluated in a `function` becomes the return value.
@@ -1075,7 +1086,7 @@ myfun(15)
.comment[`function()` itself returns the last evaluated value even without including `return()` function.]
---
-## Return values
+# Return values
.small[
It can be useful to explicitly `return()` if the routine should end early, jump out of the function and return a value.
@@ -1115,7 +1126,7 @@ simplefun2(1, 2)
]
]
---
-## Challenge 6 ![:cube]()
+# Challenge 6 ![:cube]()
Using what you have just learned on functions and control flow, create a function named `bigsum` that takes two arguments `a` and `b` and:
@@ -1124,7 +1135,7 @@ Using what you have just learned on functions and control flow, create a functio
2. Else, returns the sum of `a` and `b`.
---
-## Challenge 6: Solution ![:cube]()
+# Challenge 6: Solution ![:cube]()
@@ -1158,7 +1169,7 @@ bigsum <- function(a, b) {
---
-## Accessibility of variables
+# Accessibility of variables
It is essential to always keep in mind where your variables are, and whether they are defined and accessible:
@@ -1167,7 +1178,7 @@ It is essential to always keep in mind where your variables are, and whether the
![:faic](arrow-right) Variables defined .alert[outside] a function are accessible inside. But it is NEVER a good idea, as your function will not function if the outside variable is erased.
---
-## Accessibility of variables
+# Accessibility of variables
```{r, error = TRUE}
var1 <- 3 # var1 is defined outside our function
@@ -1186,7 +1197,7 @@ vartest() # calling the function again doesn't work anymore
```
---
-## Accessibility of variables
+# Accessibility of variables
.alert[Mandatory tip.] Use arguments then!
@@ -1204,8 +1215,7 @@ var1 # var1 still has the same value
```
---
-
-## Accessibility of variables
+# Accessibility of variables
.pull-left[
.alert[Tip.] Be very careful when creating variables inside a conditional statement as the variable may never have been created and cause (sometimes imperceptible) errors.
@@ -1243,8 +1253,7 @@ class: inverse, center, middle
# Good programming practices
---
-
-## Why should I care about programming practices?
+# Why should I care about programming practices?
- To make your life easier;
- To achieve greater readability and makes sharing and reusing your code a lot less painful;
@@ -1252,8 +1261,7 @@ class: inverse, center, middle
.center[.large[Pay attention to the next tips!]]
---
-
-## Keep a clean and nice code
+# Keep a clean and nice code
Proper indentation and spacing is the first step to get an easy to read code:
@@ -1268,8 +1276,7 @@ Proper indentation and spacing is the first step to get an easy to read code:
---
-
-## Keep a clean and nice code
+# Keep a clean and nice code
On the left, code is not spaced. All brackets are in the same line, and it looks "messy".
@@ -1284,8 +1291,7 @@ if(b==0){print("b zero")}else print(b)}
]
]
---
-
-## Keep a clean and nice code
+# Keep a clean and nice code
On the left, code is not spaced. All brackets are in the same line, and it looks "messy". On the right, it looks more organized, no?
.small[
@@ -1317,8 +1323,7 @@ if(a < b){
]
---
-
-## Use functions to simplify your code
+# Use functions to simplify your code
Write your own function:
1. When portion of the code is repeated more than twice in your script;
@@ -1327,8 +1332,7 @@ Write your own function:
This would also reduce the number of potential errors done by copy-pasting, and the time needed to correct them.
---
-
-## Use functions to simplify your code
+# Use functions to simplify your code
Let's modify the example from **Challenge #3** and suppose that all $CO_2$ uptake from Mississipi plants was overestimated by 20 and Quebec underestimated by 50.
.small[ .pull-left[
@@ -1370,7 +1374,7 @@ newCO2 <- recalibrate(newCO2, "Quebec", +50)
]
]
---
-## Use meaningful names for functions
+# Use meaningful names for functions
Same function as before, but with vague names.
.pull-left[
@@ -1394,7 +1398,7 @@ rc <- function(c, t, b) {
.comment[Whenever possible, avoid using names of existing `R` functions and variables to avoid confusion and conflits.]
---
-## Use comments
+# Use comments
.alert[Final tip]. Add comment to describe what your code does, how to use its arguments or a detailed step-by-step description of the function.
diff --git a/workshop05-en/workshop05-en.html b/workshop05-en/workshop05-en.html
index 849e652..5d49fd6 100644
--- a/workshop05-en/workshop05-en.html
+++ b/workshop05-en/workshop05-en.html
@@ -1,5 +1,5 @@
-
+