library(tidyverse)
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 = 5, number2 = 3)## [1] 8
# Create the mySum() function, and use it to calculate the sum of 13 and 1989.
mySum(13,1989)## [1] 2002
#What happens when we calculate the sum of NA and 1989?
mySum(NA, 1989)## [1] NA
# Creating a function called fun1
fun1 <- function(x, y) {
return(x + y)
}
# Creating a function called fun_2
fun_2 <- function(x, y) {
return(x - y)
}# Good naming of functions
# Creating a function called computeSum
computeSum <- function(number1, number2) {
return(number1 + number2)
}
# Creating a function called computeDiff
computeDiff <- function(number1, number2) {
return(number1 - number2)
}# Creating a function called mySum with 2 required arguments, 1 optional argument
myNewSum <- function(number1, number2, remove.na = TRUE) {
if(remove.na) {
#if remove.na s True replace NA values with 0
calcSum <- ifelse(is.na(number1), 0, number1) +
ifelse(is.na(number2), 0, number2)
} else {
#otherwise add the two numbers
calcSum <- number1 + number2
}
return(calcSum)
}ifelse(condition, valueifconditionTrue, valueif conditionFalse)
#Read the source code for each of the following three functions, determine the purpose of each function, and propose better function names.
#Checks if a string begins with a given prefix
Check_prefix <- function(string, prefix) {
str_sub(string, 1, nchar(prefix)) == prefix
}
Check_prefix(string = "anti-hero", prefix = "anti")## [1] TRUE
Check_prefix(string = "heo-anti", prefix = "anti")## [1] FALSE
#Create a function to drop the last value
drop_last_value <- function(x) {
if (length(x) <= 1){
#return NULL if no value
return(NULL)
}
else {
#Drop last value
x[-length(x)]
}
}
drop_last_value(1:5)## [1] 1 2 3 4
drop_last_value(c("gvsu","GV","LAKERS"))## [1] "gvsu" "GV"
#Create function to calculate harmonic mean
harmonic_mean <- function(x) {
1 / (mean(1 / x))
}
#Crete function to calculate geometric mean
geometric_mean<-function(values){
n<-length(x)
return(prod(x)^(1/n))
}
geometric_mean(1:5)## Error in geometric_mean(1:5): object 'x' not found
mean(1:5)## [1] 3
Conditional execution, warnings and errors
mean(c("GVSU", 5))## Warning in mean.default(c("GVSU", 5)): argument is not numeric or logical:
## returning NA
## [1] NA
# Function to calculate square root
calcSqrt <- function(val) {
if (val >= 0) {
return(val^0.5)
} else {
stop("val is negative but must be >= 0!")
return(NaN)
}
}
calcSqrt(4)## [1] 2
calcSqrt(-9)## Error in calcSqrt(-9): val is negative but must be >= 0!
chain if else statements
foodType <- function(food) {
food<-str_to_lower(food)
if (food %in% c("apple", "orange", "banana")) {
return("fruit")
} else if(food %in% c("broccoli", "asparagus")) {
return("vegetable")
} else {
return("other")
}}
foodType("Reese's Puffs")## [1] "other"
foodType("apple")## [1] "fruit"
foodType("BANANA")## [1] "fruit"
#Create a function called is_whole_number(), which checks if a given value is a whole number (e.g.,0, 1, 2, …) or not.
is_whole_number<-function(number){
if (floor(number)==number & number>=0){
return(TRUE)
} else{
return(FALSE)
}
}
is_whole_number(0)## [1] TRUE
is_whole_number(2)## [1] TRUE
is_whole_number(-1)## [1] FALSE
#The ^ operator raises a number to a specified power in R. 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(number, power){
if(number<0 &!(is_whole_number(power))){
warning("🚩🚩🚩🚩Hey!! that number is negative and power is not a whole number")
return(NaN)
}
return(number^power)
}
#Use your function to calculate 4^(2), (-9)^(2), 3^(1/3), and (-3)^(1/3).
raise_power(4,-2)## [1] 0.0625
raise_power(-2,9)## [1] -512
raise_power(3,1/3)## [1] 1.44225
raise_power(-3,1/3)## [1] NaN
The ifelse()function
# 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)
}
#Create the myNewSum() function, and use it to calculate the sum of 13 and 1989
myNewSum(13,1989)## [1] 2002
#What happens when we calculate the sum of NA and 1989 using myNewSum()?
myNewSum(NA, 1989)## [1] 1989
myNewSum(NA, 1989)## [1] 1989
Logical operators
# The 'or' operator
(3 < 5) || (-1 > 0)## [1] TRUE
# The 'and' operator
(3 < 5) && (-1 > 0)## [1] FALSE
# Checking Equality
# 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(-5)## [1] TRUE
any_negative(c(-5,0,1,2))## [1] TRUE
any_negative(c(0,1,2))## [1] FALSE
#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?
(1:4 < 4) & (1:4 > 1)## [1] FALSE TRUE TRUE FALSE
(1:4 < 4) && (1:4 > 1)## [1] FALSE
The first one does what the code is intended to do.
Modulus
#For positive numbers, the Modulus is the remainder of the division of two numbers. For example, 10 divided by 3 is 1, so 10 modulus 3 is 1. The modulus operator in R is implemented using %% as below:
# 10 mod 3
10 %% 3## [1] 1
# 10 mod 2
10 %% 2## [1] 0
# 10 mod 5
10 %% 5## [1] 0
# 12 mod 5
12 %% 5## [1] 2
# Write a function to check if a number is even or odd that returns a vector containing the values “even”, “odd”, or “not an integer” depending on its input.
evenOrOdd<- function(number){
if (number%%2==0 & floor(number) ){
return("even")
}else if(number%%2!=0 & floor(number)){
return("odd")
}else{
return("not an integer")
}
}
evenOrOdd(2) ## [1] "even"
evenOrOdd(0.6)## [1] "not an integer"
evenOrOdd(-1)## [1] "odd"