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
### <b>
add_up <- function(first, second) {
### </b>
result <- first + second
### <b>
second - first
}
add_up(3, 5) ### </b>
[1] 2
add_up <- function(first, second) {
# Calculate the result
result <- first + second
# And return it
### <b>
result
### </b>
}
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.