{hyenaR}
:hyenaR
v0.9.999941🎉{drat}
to access the new version of {hyenaR}
.library(hyenaR) ## For our hyena specific functions
library(dplyr) ## For most data wrangling
library(ggplot2) ## For plotting
library(lubridate) ## Working with dates
library(tidyr) ## Extra data wrangling functions
library(stringr) ## Working with text
library(waldo) ## To compare objects
library(skimr) ## Inspect data
library(purrr) ## For loops in the tidyverse
[1] "Median time: ~1.04s"
[1] "Median time: ~387ms"
Reproducible, consistent behaviour.
Great for collaboration.
The ‘Rule of Three’
You can specify the value of each argument explicitly
Note
Not all functions need arguments!
Using default values can make functions more flexible but still user friendly.
Using default values can make functions easier to use, but still flexible.
By default, a function returns the last value output by the code…
What will this return?
[1] 10
Use return()
if you want to be specific.
Warning
Everything after return()
is not run!
What will this return?
[1] 21
return()
can be more efficient!
is_even <- function(object){
## Check if a number is 0...
if (object == 0) {
output <- NA
}
## THEN check if a number is >0 and even
if (object > 0 & object %% 2 == 0) {
output <- "even"
}
## THEN check if a number is >0 and odd
if (object > 0 & object %% 2 != 0) {
output <- "odd"
}
## Return the output
output
}
return()
can be more efficient!
is_even_new <- function(object){
## If number is 0...return NA and stop!!
if (object == 0) {
return(NA)
}
## Otherwise...check if a number is >0 and even
if (object > 0 & object %% 2 == 0) {
output <- "even"
}
## and check if a number is >0 and odd
if (object > 0 & object %% 2 != 0) {
output <- "odd"
}
## Return the output
output
}
return()
can be more efficient!
# A tibble: 2 × 3
expression median `itr/sec`
<chr> <bch:tm> <dbl>
1 is_even(0) 574ns 1082427.
2 is_even_new(0) 164ns 1886342.
Default error messages are often hard to understand.
Use stop()
to create your own error message!
Use warning()
to flag things that can work but might cause problems.
add <- function(number, addition = 1){
if (is.character(number) | is.character(addition)) {
stop("The arguments 'number' and 'addition' cannot be characters!")
}
if (is.logical(number) | is.logical(addition)) {
warning("Coercing logical value to numeric.\n")
}
number + addition
}
add(number = 10, addition = TRUE)
Warning in add(number = 10, addition = TRUE): Coercing logical value to numeric.
[1] 11
browser()
debug()
trace()
browser()
can help debug a function you are creating!
The function will stop at the point where we add browser()
…
Use the ‘expr’ argument in browser()
to debug in certain conditions!
Use the ‘expr’ argument in browser()
to debug in certain conditions!
debug()
can be used for any function (even ones you didn’t write!)
Warning
You will need to undebug()
a function (or use debugonce()
)
If you identify a problem in another function, you can use trace(edit = TRUE)
to tweak it.
Try it yourself.
average_age_firstrepro <- function(sex, birth_year, na.rm = FALSE){
## Create start and end date for the target year
start_date <- paste('birth_year', "01/01", sep = "_")
end_date <- paste('birth_year', "12/31", sep = "_")
## Extract all individuals born in that year and their age at first birth
all_births <- create_id_starting.table(from = start_date, to = end_date,
sex = sex,
lifestage = "cub", lifestage.overlap = "start") %>%
dplyr::mutate(firstbirth = fetch_id_date.birth.first(ID)) %>%
dplyr::mutate(age = fetch_id_age(ID, at = firstbirth))
## Determine an average age at first birth
avg_age <- mean(all_births$age, na.rm = na.rm)
## Return the number
return(avg_age)
}
Why doesn’t this code work?
Note
There might be more than one problem…