library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ ggplot2 3.3.6     ✔ purrr   0.3.4
## ✔ tibble  3.1.8     ✔ dplyr   1.0.9
## ✔ tidyr   1.2.0     ✔ stringr 1.4.1
## ✔ readr   2.1.2     ✔ forcats 0.5.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
library(stringr)
# Creating a function called mySum with 2 required arguments
mySum <- function(number1, number2) {
  return(number1 + number2)
}

# Defaulting to order of arguments in function
mySum(5, 3)
## [1] 8
# Manually specifying arguments
mySum(number1 = 13, number2 = 1989)
## [1] 2002
mySum(number1 = NA, number2 = 1989)
## [1] NA

You try

# Creating a function called 'myNewSum' that adds two numbers. 
myNewSum <- function(number1, number2, remove.na = TRUE) {
  # Defines the function 'calcSum' based on whether it receives 'NA' as an output, redefining both numbers inputted as zero. 
  if(remove.na) {
    calcSum <- ifelse(is.na(number1), 0, number1) + 
         ifelse(is.na(number2), 0, number2)
  } else {
    # Defines the function 'calcSum' as long as there is no 'NA'. 
    calcSum <- number1 + number2
  }
  # Outputs calcSum
  return(calcSum)
}
# Creates a function that checks if a string has a given prefix 
starts_with_prefix <- function(string, prefix) {
  str_sub(string, 1, nchar(prefix)) == prefix
}

starts_with_prefix("anti-hero", prefix = "anti")
## [1] TRUE
starts_with_prefix("anti-hero", prefix = "hero")
## [1] FALSE
# Creating function that drops last value of vector. 
drop_last <- function(x) {
  if (length(x) <= 1) return(NULL)
  x[-length(x)]
}

drop_last(1:5)
## [1] 1 2 3 4
drop_last(c("GVSU","SVSU", "Ashland", "Ferris State"))
## [1] "GVSU"    "SVSU"    "Ashland"
drop_last("GVSU")
## NULL
# Creating a function that calculates the harmonic mean. 
harmonic_mean <- function(x) {
  1 / (mean(1 / x))
}

harmonic_mean(1:50)
## [1] 11.11307
mean(1:50)
## [1] 25.5
# Creating geometric mean function.
geometricMean <- function(values) {
  n <- length(values)
  totalProd <- prod(values)
  return(totalProd^(1 / n))
}

geometricMean(1:5)
## [1] 2.605171
mean(1:5)
## [1] 3
# Function to calculate square root
calcSqrt <- function(val) {
if (val >= 0) {
  return(val^0.5)
} else {
  warning("val is negative but must be >= 0!")
  return(NaN)
}
}

calcSqrt(4)
## [1] 2
## [1] 2
calcSqrt(-9)
## Warning in calcSqrt(-9): val is negative but must be >= 0!
## [1] NaN
## [1] NaN

Chained if else statements.

a_b_or_c <- function() {
  firstLetter <- str_sub(string, start = 1, end = 1)
  if (condition1) {
  return("Starts with a!")
  # do that
} else if (condition2) {
  # do something else
  return("Starts with b!")
} else {
  return("Doesn't start with a or b!")
  # 
}
  
}
#Create a function called is.whole.number(), which checks if a given value is a whole number. 

is.whole.number <- function() {
  roundedx <- round(x)
  return(x == roundedx)
}

#Alternative way
is.whole.number <- function(x) {
  flooredx <- floor(x)
  return(x == flooredx)
}

is.whole.number(3.1415)
## [1] FALSE
#Create a function that raises a number to a specified power and returns a warning and an NaN value if the number is negative and the power is not a whole number. 
raise_power <- function(x, power) {
  if(x < 0 & (is.whole.number(x) == FALSE)) {
    warning("Check yoruself before you wreck yourself! That power is negative and the number is not a whole number...")
    return(NaN)
  } else {
    return(x^power)
  }
}

raise_power(x = 4, power = 2)
## [1] 16
raise_power(x = -9, power = 2)
## [1] 81
raise_power(x = 3, power = 1/3)
## [1] 1.44225
raise_power(x = -3, power = 1/3)
## [1] NaN

The ifelse() function

xs <- c(-2, -1, 0, 1, 2)

ifelse(xs > 0, xs, NA)
## [1] NA NA NA  1  2
# Creating a function called mySum with 2 required arguments, 1 optional argument
myNewSum <- function(number1, number2, remove.na = TRUE) {
  if(remove.na) {
    calcSum <- ifelse(is.na(number1), 0, number1) + 
         ifelse(is.na(number2), 0, number2)
  } else {
    calcSum <- number1 + number2
  }
  return(calcSum)
}
myNewSum(13, 1989)
## [1] 2002
myNewSum(NA, 1989)
## [1] 1989
myNewSum(NA, 1989, remove.na = FALSE)
## [1] NA

Logical operators.

# The 'or' operator
(3 < 5) || (-1 > 0)
## [1] TRUE
# The 'and' operator
(3 < 5) && (-1 > 0)
## [1] FALSE
# The 'equals' operator
3 == 5
## [1] FALSE
(4/2) == 2
## [1] TRUE
3 != 5
## [1] TRUE
# Vectorized examples
1:4
## [1] 1 2 3 4
1:4 == 3
## [1] FALSE FALSE  TRUE FALSE
(1:4 < 4) & (1:4 > 1)
## [1] FALSE  TRUE  TRUE FALSE
(1:4 < 4) | (1:4 > 1)
## [1] TRUE TRUE TRUE TRUE
# Create a function that takes a numeric vector as input, and returns a single boolean value indicating whether or not the vector has any negative values.
any_negative <- function(numbers) {
  return(any(numbers < 0)) 
}

any_negative(c(1,2,3,0))
## [1] FALSE
any_negative(c(1,2,3))
## [1] FALSE
any_negative(c(1,2,3,-1))
## [1] TRUE
#  Does the code (1:4 < 4) & (1:4 > 1) produce the same result as (1:4 < 4) && (1:4 > 1)? Which code achieves what appears to be its intended purpose?

#Looks at all values
(1:4 < 4) & (1:4 > 1)
## [1] FALSE  TRUE  TRUE FALSE
#Only looks at the 1st value of each vector
(1:4 < 4) && (1:4 > 1)
## [1] FALSE
#The first one is the one we want because the second one can be misleading.