Functions in R programming language

  • We can do object oriented programming in R. In fact, everything in R is an object.
  • An object is a data structure having some attributes and methods which act on its attributes.
  • Class is a blueprint for the object. As, many houses can be made from a description, we can create many objects from a class.
  • While most programming languages have a single class system, R has three class systems. Namely, S3, S4 and more recently Reference class systems.
  • A set of statements, organized together to perform a specific task is known as a “function.
  • Functions are used to provide reusability (reduce complexity)and abstraction.
  • An R function is
    • Created by using the keyword ‘function’.
    • Written to carry out a specified task (may or may not return one or more output values).
    • May or may not have arguments.
    • Contains a body in which code is written.
https://www.javatpoint.com/r-built-in-functions https://perfectmaths.files.wordpress.com/2011/06/function_machine_fx.png https://mathinsight.org/function_examples

Components of Functions

  • There are four components of function in R:
    1. Function Name-This is the actual name of the function. In R, the function is stored in R environment as an object with its name.
    2. ArgumentsIn R, an argument is
      • a placeholder (We pass a value to the argument when a function is invoked)
      • is optional ( a function may or may not contain arguments)
      • can have default values also.
    3. Function BodyIt contains a set of statements which defines what the function does (in curly braces).
    4. Return valueIt is the last expression in the function body which is to be evaluated.

Script for R functions

  • student.history.exam.marks <- c( 50L,60L, 70L,80L) #integer vector
  • student.history.quiz.marks <- c( 1L, 2L, 3L, 4L) #integer vector
  • student.history.total.marks<-(student.history.exam.marks+student.history.quiz.marks)
  • student.history.total.marks
  • [1] 51 62 73 84
  • Get.total.marks<-function(exam.marks,quiz.marks)
  • {total.marks<-exam.marks + quiz.marks
  • total.marks
  • }
  • student.geography.exam.marks <- c( 50L,60L, 70L,80L) #integer vector
  • student.geography.quiz.marks <- c( 5L, 6L, 7L, 8L) #integer vector
  • student.geography.total.marks<-Get.total.marks(student.geography.exam.marks,student.geography.quiz.marks)
  • student.geography.total.marks
  • [1] 55 66 77 88
  • monthwise.bill<-function(rent,electricity,grocery)
  • {monthwise.bill<-rent + electricity + grocery
  • monthwise.bill
  • }
  • rita.rent<-c(700L,700L,700L,700L,700L,700L)#integer vector
  • rita.electricity<-c(100L,120L,140L,160L,180L,200L)#integer vector
  • rita.grocery<-c(200L,180L,160L,140L,120L,100L)#integer vector
  • rita.monthwise.bill<-monthwise.bill(rita.rent,rita.electricity,rita.grocery)
  • rita.monthwise.bill
  • [1] 1000 1000 1000 1000 1000 1000
Function Naming Guidelines
  • Google R style guide
    • initial capital letter
    • with no space or dots
    • capital letter for words sepaartion
  • PascalCase is similar to camelCase, except the first letter in PascalCase is always capitalized.
  • Camel case is the practice of writing phrases without spaces or punctuation, indicating the separation of words with a single capitalized letter, and the first word starting with either case.Examples include “iPhone”, “JavaScript”, and “eBay”.
Arguement matching/mapping
  • When there are multiple arguments in a function.
  • Arguement maching is mapping between values passed from the function invocation to arguements of the function definition.
  • Match by position-First value is passed as first arguement while second value is passed as second arguement.
  • Get.total.marks<-function(exam.marks,quiz.marks)
  • {total.marks<-exam.marks – quiz.marks
  • total.marks
  • }
  • Get.total.marks(c(50L,60L, 70L, 80L), c(5L,6L,7L,8L))
  • [1] 45 54 63 72
  • Get.total.marks(c(5L,6L,7L,8L), c(50L,60L, 70L, 80L))
  • [1] -45 -54 -63 -72
  • Match by name-use of agruement names in function call helps to reorder the values in the function.
  • GetTotalMarks<-function(exam.marks, viva.marks)
  • {GetTotalMarks<-exam.marks-viva.marks
  • GetTotalMarks
  • }
  • GetTotalMarks(exam.marks= c(50L,60L,70L,80L), viva.marks= c(5L,6L,7L,8L))
  • [1] 45 54 63 72
  • GetTotalMarks(viva.marks= c(5L,6L,7L,8L), exam.marks= c(50L,60L,70L,80L))
  • [1] 45 54 63 72
Default arguement
  • An arguement which has some default value and is not required to specify in a function call.
  • We extend the original function by adding one more arguement and assign a fixed value to it in the function definition itself . Then adding the same arguement in the function body also(2 here).
  • We can call the function without specifying the value for this default arguement.
  • GetTotalMarks<-function(exam.marks, viva.marks, bonus.marks =2L )
  • {GetTotalMarks<-exam.marks + viva.marks + bonus.marks
  • GetTotalMarks
  • }
  • GetTotalMarks(exam.marks= c(50L,60L,70L,80L), viva.marks= c(5L,6L,7L,8L))
  • [1] 57 68 79 90
  • We can also override the default value by specifying it. We can do so by passing one more integer vector during function call.
  • GetTotalMarks(exam.marks= c(50L,60L,70L,80L), viva.marks= c(5L,6L,7L,8L), bonus.marks= c(1L,1L,0L,0L))
  • [1] 56 67 77 88
Additional arguements in R using Ellipsis/Triple dots
  • Ellipsis is also a function arguement. It is a special arguement meaning “anything else”.
  • We use it when we have a function with few known arguements, and we want to use some more arguements but are not sure what those additional arguements could be.
  • In R Ellipsis should be the last arguement in the function.
  • Using Ellipsis we can pass additional arguemnts to the function without changing the function definition.
  • These additional arguements cannot be mapped either using position or using name. We use ellipsis to map these additional arguements.
  • Typically, ellipsis are used to add additional arguements to some external functions. Here, we have passed additional arguements to sum function.
  • GetTotalMarks<-function(exam.marks, viva.marks, bonus.marks =2L,… )
  • {GetTotalMarks<-exam.marks + viva.marks + bonus.marks + sum(…)
  • GetTotalMarks
  • }
  • GetTotalMarks(exam.marks= c(50L,60L,70L,80L), viva.marks= c(5L,6L,7L,8L), supw.marks=3)
  • [1] 60 71 82 93
  • GetTotalMarks(exam.marks= c(50L,60L,70L,80L), viva.marks= c(5L,6L,7L,8L), supw.marks=3, awa.marks=2)
  • [1] 62 73 84 95
  • If we want to see or use additional arguements explicitly, then we can wrap ellipsis in list.
  • GetTotalMarks<-function(exam.marks, viva.marks, bonus.marks =2,… )
  • {GetTotalMarks<-exam.marks + viva.marks + bonus.marks + sum(…)
  • extra.arguements<-list(…)
  • print(extra.arguements)
  • GetTotalMarks
  • }
  • GetTotalMarks(exam.marks= c(50L,60L,70L,80L), viva.marks= c(5L,6L,7L,8L), supw.marks=3)
  • $supw.marks
  • [1] 3
  • [1] 60 71 82 93
  • GetTotalMarks(exam.marks= c(50L,60L,70L,80L), viva.marks= c(5L,6L,7L,8L), supw.marks=3, awa.marks=2)
  • $supw.marks
  • [1] 3
  • $awa.marks
  • [1] 2
  • [1] 62 73 84 95
Lazy evaluation of default arguement in R function
  • Evaluation of a default arguement (whose value is set to another variable) is deferred until it is first used.
  • We would not supply any value for default arguement, even then R will not raise any error in execution of first line. It will be evaluated only after first use. This behavior is known as lazy evaluation.
  • GetTotalMarks<-function(exam.marks, viva.marks, extra.marks = avg.viva.marks )
  • {avg.viva.marks<- mean(viva.marks)
  • GetTotalMarks<-exam.marks + viva.marks + extra.marks
  • GetTotalMarks
  • }
  • GetTotalMarks(exam.marks= c(50L,60L,70L,80L), viva.marks= c(5L,6L,7L,8L))#to call function by passing two interger vector as vlaues to the arguements.
  • [1] 61.5 72.5 83.5 94.5
Multiple return values from a function
  • There is no need of explicit return statement for the functions which return only a single value . By default, last line of function is treated as return value.
  • If we need multiple return values from a function we can use a list with the return statement.
  • To get any individual value we can use any of list-subsetting technique.
  • physical.activity<-function(walk, cardio){
  • total.physical.activity<-(walk+ cardio)
  • average.physical.activity<-mean(total.physical.activity)
  • return(list(total.physical.activity,average.physical.activity ))
  • }
  • physical.activity(walk= c(2L,3L,2L), cardio= c(1L,2L, 1L)) #to call function by passing two interger vector as vlaues to the arguements.
  • [[1]]
  • [1] 3 5 3
  • [[2]]
  • [1] 3.666667
  • physical.activity<-function(walk, cardio){
  • total.physical.activity<-(walk+ cardio)
  • average.physical.activity<-mean(total.physical.activity)
  • return(list(total.time = total.physical.activity, avg.time = average.physical.activity))
  • }
  • physical.activity(walk= c(2L,3L,2L),cardio= c(1L,2L, 1L))
  • $total.time
  • [1] 3 5 3
  • $avg.time
  • [1] 3.666667
Functions as First class object
  • Functions are first-class R objects. So, we can:
    1. look into them
    2. assign them to some other variable
    3. pass them as arguement to some other function
  • GetTotalMarks<-function(exam.marks, viva.marks ){
  • GetTotalMarks<-exam.marks + viva.marks
  • GetTotalMarks
  • }
  • GetTotalMarks(exam.marks= c(50L,60L,70L,80L), viva.marks= c(5L,6L,7L,8L)) #to call function by passing two interger vector as vlaues to the arguements.
  • [1] 55 66 77 88
  • (01) To look into function object
  • GetTotalMarks # retrun whole function by using function name without parenthesis
  • function(exam.marks, viva.marks ){
  • GetTotalMarks<-exam.marks + viva.marks
  • GetTotalMarks
  • }
  • formals(GetTotalMarks) #extract/access arguements fo function
  • $exam.marks
  • $viva.marks
  • body(GetTotalMarks) # extract/access body of function
  • {
  • GetTotalMarks <- exam.marks + viva.marks
  • GetTotalMarks
  • }
  • (02) To assign a function to another variable
  • Fall2020.total.marks <- GetTotalMarks #to assign a function to another variable
  • Fall2020.total.marks #newly created function has the same content
  • function(exam.marks, viva.marks ){
  • GetTotalMarks<-exam.marks + viva.marks
  • GetTotalMarks
  • }
  • (03) To use functions as arguement to other function
  • GetTotalMarks(exam.marks= c(50L,60L,70L,80L), viva.marks= c(5L,6L,7L,8L))# traditional method to call a function
  • [1] 55 66 77 88
  • do.call(GetTotalMarks, list(exam.marks= c(50L,60L,70L,80L), viva.marks= c(5L,6L,7L,8L)))# pass the function object as first parameter to do.call method and to call arguements of function we create a list and pass it as second parameter
  • [1] 55 66 77 88
Anonymous Function
  • Anonymous function is a function without any name.
  • Used to create small functions.
  • Here, we have used do.call method using anonymous function as first parameter and to call arguements of function we create a list and pass it as second parameter
  • do.call(function(exam.marks, viva.marks){
  • exam.marks + viva.marks},list(exam.marks= c(50L,60L,70L,80L), viva.marks= c(5L,6L,7L,8L)))
  • [1] 55 66 77 88
  • If, there is only one line in anonymous function(exam.marks + viva.marks), we can remove curly braces.
  • do.call(function(exam.marks, viva.marks){
  • exam.marks + viva.marks},list(exam.marks= c(50L,60L,70L,80L), viva.marks= c(5L,6L,7L,8L)))
  • [1] 55 66 77 88
  • Parameter is a variable in a method definition.
  • Argument is the actual value of this variable that gets passed to function.

REFERENCES