Learning Objectives

Following this assignment students should be able to:

  • use, modify, and write custom functions
  • use the output of one function as the input of another
  • understand and use the basic relational operators
  • use an if statement to evaluate conditionals

Reading

Lecture Notes

  1. Functions
  2. Conditionals

Exercises

  1. -- Writing Functions --

    Write a function that converts pounds to grams (there are 453.592 grams in one pound). It should take a value in pounds as the input and return the equivalent value in grams (i.e., the number of pounds times 453.592). Use that function to calculate how many grams there are in 3.75 pounds.

    [click here for output]
  2. -- Use and Modify --

    The length of an organism is typically strongly correlated with it’s body mass. This is useful because it allows us to estimate the mass of an organism even if we only know its length. This relationship generally takes the form:

    Mass = a * Lengthb

    Where the parameters a and b vary among groups. This allometric approach is regularly used to estimate the mass of dinosaurs since we cannot weigh something that is only preserved as bones.

    The following function estimates the mass of an organism in kg based on it’s length in meters for a particular set of parameter values, those for Theropoda (where a has been estimated as 0.73 and b has been estimated as 3.63; Seebacher 2001).

    get_mass_from_length_theropoda <- function(length){
      mass <- 0.73 * length ** 3.63
      return(mass)
    }
    
    1. Add a comment to this function so that you know what it does.
    2. Use this function to print out the mass of a Spinosaurus that is 16 m long based on it’s reassembled skeleton. Spinosaurus is a predator that is bigger, and therefore, by definition, cooler, than that stupid Tyrannosaurus that everyone likes so much.
    3. Create a new version of this function called get_mass_from_length() that estimates the mass of an organism in kg based on it’s length in meters by taking length, a, and b as parameters. To be clear we want to pass the function all 3 values that it needs to estimate a mass as parameters. This makes it much easier to reuse for all of the non-theropod species. Use this new function to estimate the mass of a Sauropoda (a = 214.44, b = 1.46) that is 26 m long.
    [click here for output]
  3. -- Nested Functions --

    This is a follow up to Use and Modify.

    Measuring things using the metric system is the standard approach for scientists, but when communicating your results more broadly it may be useful to use different units (at least in some countries). Write a function that converts kilograms into pounds (there are 2.205 pounds in a kilogram). Use that function along with your dinosaur mass function from Use and Modify to estimate the weight, in pounds, of a 12 m long Stegosaurus (12 m is about as big as they come and nothing gets folks excited like a giant dinosaur). In Stegosauria, a has been estimated as 10.95 and b has been estimated as 2.64 (Seebacher 2001).

    [click here for output]
  4. -- Choice Operators --

    Create the following variables.

    w <- 10.2
    x <- 1.3
    y <- 2.8
    z <- 17.5
    dna1 <- "attattaggaccaca"
    dna2 <- "attattaggaacaca"
    

    Use them to print whether or not the following statements are

    TRUE or FALSE.

    1. w is greater than 10
    2. w + x is less than 15
    3. x is greater than y
    4. 2 * x + 0.2 is equal to y
    5. dna1 is the same as dna2
    6. dna1 is not the same as dna2
    7. w is greater than x, and y is greater than z
    8. x times w is between 13.2 and 13.5
    9. dna1 is longer than 5 bases (use nchar() to figure out how long a string is), or z is less than w * x
    [click here for output]
  5. -- Simple If Statement --

    To determine if a file named thesis_data.csv exists in your working directory you can use the code:

    file.exists('thesis_data.csv')
    

    This code returns TRUE if the files exists and FALSE if it does not.

    1. Write an if statement that loads the file using read.csv() only if the file exists.
    2. Add an else clause that prints “OMG MY THESIS DATA IS MISSING. NOOOO!!!!” if the file doesn’t exist.
    [click here for output]
  6. -- Complete the Code --

    The following function is intended to check if two geographic points are close to one another. If they are it should return TRUE. If they aren’t, it should return FALSE. Two points are considered near to each other if the absolute value of the difference in their latitudes is less than one and the absolute value of the difference in their longitudes is less than one.

    1. Fill in the _________ in the function to make it work.

      near <- function(lat1, long1, lat2, long2){
          # Check if two geographic points are near each other 
          if ((abs(lat1 - lat2) < 1) & (_________){
              near <- TRUE
          } else {
              near <- _________
          }
          return(near)
      }
      
    2. Improve the documentation for the function so that it is clear what near means and what output the user should expect.
    3. Check if Point 1 (latitude = 29.65, longitude = -82.33) is near Point 2 (latitude = 41.74, longitude = -111.83).
    4. Check if Point 1 (latitude = 29.65, longitude = -82.33) is near Point 2 (latitude = 30.5, longitude = -82.8).
    5. Create a new version of the function that improves it by allowing the user to pass in a parameter that sets what “near” means. To avoid changing the existing behavior of the function (since some of your lab mates are using it already) give the parameter a default value of 1.
    6. Improve the documentation for the new function so that it reflects this new behavior
    7. Check if Point 1 (latitude = 48.86, longitude = 2.35) is near Point 2 (latitude = 41.89, longitude = 2.5), when near is set to 7.
    [click here for output]
  7. -- Choices with Functions --

    The UHURU experiment in Kenya has conducted a survey of Acacia drepanolobium among each of their ungulate exclosure treatments. Data for the survey is available here in a tab delimited ("\t") format. Each of the individuals surveyed were measured for branch circumference (CIRC) and canopy width (AXIS1) and was identified for the associated ant-symbiont species present (ANT).

    The following function takes a subset of the data for a given ANT symbiont and evaluates the linear regression (lm()) for a given relationship, returning the symbiont species used for the subset and the r2 of the model.

    report_rsquared <- function(data, species, formula){
      subset <- dplyr::filter(data, ANT == species)
      test <- lm(formula, data = subset)
      rsquared <- round(summary(test)$r.squared, 3)
      output <- data.frame(species = species, r2 = rsquared)
      return(output)
    }
    
    1. Execute the function using the UHURU data and specifying species = "CM" and formula = "AXIS1~CIRC".
    2. Modify the function so that it also determines if() the rsquared is significant based on a given threshold. The modified function should return() the species, rsquared and a significance value of "S" for a relationship with an rsquared > threshold or "NS" for an rsquared < threshold.
    3. Execute your modified function for species of "CM", "CS", and "TP" given a threshold = 0.667.
    [click here for output]