Chapter 6 Functions

In short, function is a piece of code that takes some arguments, makes mumbo jumbo and returns result. All the time, through this book we were using functions that are built in base R or comes from additional packages (like dplyr). So you are now quite familiar whit the syntax that resembles typical mathematical syntax – name of a function followed by arguments in brackets - like f(x). From time to time you will need to do something in your code for few times with different arguments. In order to not repeat yourself and not copy – paste your code multiple times you can wrap your procedure in a function. The best way (as always) to understand how to do it, is to do it. To begin with something simple we will start with making basic math functions which later will lead us to simple calculator.

6.1 Simple math functions.

Simple math operations include: adding, substracting, dividing and multipling. To make our calculator slightly less boring, we can also add powers and nth rooting. To not to complicate to much things in the beginning, lets say that we want our function to take two and only two arguments. Lets look below how to code our functions:

addF <- function(x,y) {
  return(x+y)
}
subF <- function(x,y) {
  return(x-y)
}
divF <- function(x,y) {
  return(x/y)
}
mulF <- function(x,y) {
  return(x*y)
}
powF <- function(x,y) {
  return(x:y)
}
ntrF <- function(x,y) {
  return(x^(1/y))
}

6.2 Building your own calculator

Above example is of course useless and boring. So lets quickly get to making calculator, that would use one of above functions, or return results of all of them. So actually this time we will make so called wraper around previously made functions. We will use switch functionality, so besides our two parameters: x and y we will also tell our function which of the results we are interested in.

simpleCalculator <- function(x, y, mathType) {
  addF <- function(x, y) {
  return(x+y)
  }
  subF <- function(x, y) {
  return(x-y)
  }
  divF <- function(x, y) {
  return(x/y)
  }
  mulF <- function(x, y) {
  return(x*y)
  }
  powF <- function(x, y) {
  return(x^y)
  }
  ntrF <- function(x, y) {
  return(x^(1/y))
  }
  switch(mathType,
         add = addF(x, y),
         substract = subF(x, y),
         multiple = mulF(x, y),
         divide = divF(x, y),
         power = powF(x, y),
         root = ntrF(x, y),
         all = cat('The result of mathematical opereators on two numbers:',
                      paste(x, 'and', y), 'are:', '\naddition:', addF(x, y),
                      '\nsubstraction:', subF(x, y), '\nmultiplication:', mulF(x, y),
                      '\ndvision:', divF(x, y), '\nWhat is more the', y,
                      'th power of', x, 'is', powF(x, y), 'and', x, y,
                      'th root is', ntrF(x, y)))
}

simpleCalculator(25,5, 'root')
## [1] 1.903654
simpleCalculator(16,2,'all')
## The result of mathematical opereators on two numbers: 16 and 2 are: 
## addition: 18 
## substraction: 14 
## multiplication: 32 
## dvision: 8 
## What is more the 2 th power of 16 is 256 and 16 2 th root is 4

6.3 It is not over yet… Calculator shouldn’t divide be 0!

We know that division by 0 is not the best idea in the world, thus we should stop users (or ourselves) from doing it. Thus we will add an if...else statement to our function. Next time when you use 0 as a second argument you will see an error. Also, we declare mathType = 'all' as a default value, so if we omit this parameter, function will evaluate anyway.

simpleCalculator <- function(x, y, mathType = 'all') {
  if (mathType == 'divide' & y == 0) {
    return('You cannot divide by 0, please change y value.')
  } else if (mathType == 'root' & y == 0) {
    return('Root denominator is 0, cannot perform operation, please change y value.')
  } else if (mathType == 'all' & y == 0) {
    return('Y value needs to be different from 0 to make division and nth root.')
  }
  addF <- function(x, y) {
  return(x+y)
  }
  subF <- function(x, y) {
  return(x-y)
  }
  divF <- function(x, y) {
  return(x/y)
  }
  mulF <- function(x, y) {
  return(x*y)
  }
  powF <- function(x, y) {
  return(x^y)
  }
  ntrF <- function(x, y) {
  return(x^(1/y))
  }
  switch(mathType,
         add = addF(x, y),
         substract = subF(x, y),
         multiple = mulF(x, y),
         divide = divF(x, y),
         power = powF(x, y),
         root = ntrF(x, y),
         all = cat('The result of mathematical opereators on two numbers:',
                      paste(x, 'and', y), 'are:', '\naddition:', addF(x, y),
                      '\nsubstraction:', subF(x, y), '\nmultiplication:', mulF(x, y),
                      '\ndvision:', divF(x, y), '\nWhat is more the', y,
                      'th power of', x, 'is', powF(x, y), 'and', x, y,
                      'th root is', ntrF(x, y)))

}
simpleCalculator(25,0)
## [1] "Y value needs to be different from 0 to make division and nth root."
simpleCalculator(25,0, 'root')
## [1] "Root denominator is 0, cannot perform operation, please change y value."
simpleCalculator(25,0, 'divide')
## [1] "You cannot divide by 0, please change y value."
simpleCalculator(25,5)
## The result of mathematical opereators on two numbers: 25 and 5 are: 
## addition: 30 
## substraction: 20 
## multiplication: 125 
## dvision: 5 
## What is more the 5 th power of 25 is 9765625 and 25 5 th root is 1.903654