source(...)
c()
, seq()
, head()
and tail()
for (...) { ... }
my_fun <- function() { ... }
if (...) { ... } else { ... }
{ ... }
data.frame(...) rbind(df1, df2)
source("0105-step-birth-death.R") step_deterministic_birth_death
function (latest, birth.rate, death.rate) { new.births <- birth.rate * latest$count new.deaths <- death.rate * latest$count next.count <- latest$count + new.births - new.deaths data.frame(count = next.count) }
c("Hello", "Goodbye")
[1] "Hello" "Goodbye"
words <- c("Welcome", "Farewell") words[2]
[1] "Farewell"
seq()
seq(2, 4)
[1] 2 3 4
wholes <- seq(from = 3, to = 6) wholes
[1] 3 4 5 6
halves <- seq(from = 3, to = 7, by = 0.5) halves
[1] 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0
head()
and tail()
head(halves)
[1] 3.0 3.5 4.0 4.5 5.0 5.5
tail(halves, 1)
[1] 7
for (...)
loopsfor (item in vector) { do something, probably to item }
Remember, wholes
was seq(from = 3, to = 6)
:
for (whole in wholes) { print(whole) }
[1] 3 [1] 4 [1] 5 [1] 6
for (...)
loopshalves <- seq(from = 0, to = 1, by = 0.5) total <- 0 for (half in halves) { print(half) total <- total + half }
[1] 0 [1] 0.5 [1] 1
total
[1] 1.5
add_up <- function(first, second) { first + second } add_up(3, 5)
[1] 8
add_up <- function(first, second) { result <- first + second } add_up(3, 5)
add_up <- function(first, second) { result <- first + second result } add_up(3, 5)
[1] 8
add_up <- function(first, second) { result <- first + second second - first } add_up(3, 5)
[1] 2
add_up <- function(first, second) { # Calculate the result result <- first + second # And return it result } add_up(3, 5)
[1] 8
We want to calculate: \[(first + second) \times (first + second)\]
add_and_square <- function(first, second) { # Calculate the result added <- first + second squared <- added * added # And return it squared } add_and_square(3, 5)
[1] 64
Doing it all in one go increases the risk of mistakes:
add_and_square <- function(first, second) { (first + second) * first + second } add_and_square(3, 5)
[1] 29
if (...) {...}
statementsIf statements allow us to do different things depending on what has gone before in the code.
if (...) {...}
statementsif (add_and_square(3, 5) == 64) { print("Maths still works") }
if (...) {...} else {...}
if (add_and_square(3, 5) == 64) { print("Maths still works") } else { warning("We have a problem") print(add_and_square(3, 5)) }
Warning: We have a problem
[1] 29
if (...) {...} else {...}
add_and_square <- function(first, second) { # Calculate the result added <- first + second squared <- added * added # And return it squared }
if (...) {...} else {...}
if (add_and_square(3, 5) == 64) { usethis::ui_done("Maths still works") } else { usethis::ui_oops("We have a problem") }
✔ Maths still works
{ ... }
Curly brackets allow us to do lots of things all in one go. You’ve seen them in for loops, if statements, function definitions. They turn multiple R statements into one block, like a code block in RMarkdown but in regular R. Make sure you don’t forget them.
{ ... }
add_and_square <- function(first, second) added <- first + second squared <- added * added squared
[1] 0
add_and_square(3, 5)
{ ... }
added <- 0 add_and_square <- function(first, second) added <- first + second squared <- added * added squared
[1] 0
add_and_square(3, 5)
{ ... }
added <- 0 add_and_square <- function(first, second) { added <- first + second } squared <- added * added squared
[1] 0
add_and_square(3, 5)
{ ... }
added <- 0 add_and_square <- function(first, second) { added <- first + second squared <- added * added squared } add_and_square(3, 5)
[1] 64
{ ... }
Notice that they actually interfere with RMarkdown
#' ## Adding a header here works! added <- 0 add_and_square <- function(first, second) { #' ## Adding a header here doesn't work :( added <- first + second squared <- added * added squared }
first <- head(airquality) first
Ozone Solar.R Wind Temp Month Day 1 41 190 7.4 67 5 1 2 36 118 8.0 72 5 2 3 12 149 12.6 74 5 3 4 18 313 11.5 62 5 4 5 NA NA 14.3 56 5 5 6 28 NA 14.9 66 5 6
class(first)
[1] "data.frame"
last <- tail(airquality, 1) last
Ozone Solar.R Wind Temp Month Day 153 20 223 11.5 68 9 30
full <- rbind(first, last) full
Ozone Solar.R Wind Temp Month Day 1 41 190 7.4 67 5 1 2 36 118 8.0 72 5 2 3 12 149 12.6 74 5 3 4 18 313 11.5 62 5 4 5 NA NA 14.3 56 5 5 6 28 NA 14.9 66 5 6 153 20 223 11.5 68 9 30
nrow(full)
[1] 7
rm(list=ls())
This clears the environment, but so does generating a report, and rm()
can accidentally delete useful things if it’s used in the wrong place, so never use it. If you have to clear the environment, you can clear the environment manually using Session->Clear Workspace, the brush in the Environment tab, or even better use Session->Restart R to restart everything. Next:
setwd("c/d") # and more importantly setwd("c:\a\b\c\d")
This will set the working directory to a fixed place, which is very annoying if you ever move your code or more importantly if someone else tries to use it. Much better to use a Project, so please never put setwd()
into your code anywhere.
And finally:
install.packages("tibble") devtools::install_github("SBOHVM/RPiR")
This should be done before you run your code (and later we’ll show you how to make sure it is done as your code is downloaded), but your scripts should not try to install packages themselves. It’s enough that loading the library will fail if the code is run. It’s obvious what to do next if that happens.