Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Data Analysis with R, Second Edition

You're reading from   Data Analysis with R, Second Edition A comprehensive guide to manipulating, analyzing, and visualizing data in R

Arrow left icon
Product type Paperback
Published in Mar 2018
Publisher Packt
ISBN-13 9781788393720
Length 570 pages
Edition 2nd Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Tony Fischetti Tony Fischetti
Author Profile Icon Tony Fischetti
Tony Fischetti
Arrow right icon
View More author details
Toc

Table of Contents (19) Chapters Close

Preface 1. RefresheR 2. The Shape of Data FREE CHAPTER 3. Describing Relationships 4. Probability 5. Using Data To Reason About The World 6. Testing Hypotheses 7. Bayesian Methods 8. The Bootstrap 9. Predicting Continuous Variables 10. Predicting Categorical Variables 11. Predicting Changes with Time 12. Sources of Data 13. Dealing with Missing Data 14. Dealing with Messy Data 15. Dealing with Large Data 16. Working with Popular R Packages 17. Reproducibility and Best Practices 18. Other Books You May Enjoy

Functions

If we need to perform some computation that isn't already a function in R a multiple number of times, we usually do so by defining our own functions. A custom function in R is defined using the following syntax:

  > function.name <- function(argument1, argument2, ...){ 
  +   # some functionality 
  + } 

For example, if we wanted to write a function that determined if a number supplied as an argument was even, we can do so in the following manner:

  > is.even <- function(a.number){ 
  +   remainder <- a.number %% 2 
  +   if(remainder==0) 
  +     return(TRUE) 
  +   return(FALSE) 
  + } 
   
  > # testing it 
  > is.even(10) 
  [1] TRUE 
  > is.even(9) 
  [1] FALSE 

As an example of a function that takes more than one argument, let's generalize the preceding function by creating a function that determines whether the first argument is divisible by its second argument:

  > is.divisible.by <- function(large.number, smaller.number){ 
  +   if(large.number %% smaller.number != 0) 
  +     return(FALSE) 
  +   return(TRUE) 
  + } 
   
  > # testing it 
  > is.divisible.by(10, 2) 
  [1] TRUE 
  > is.divisible.by(10, 3) 
  [1] FALSE 
  > is.divisible.by(9, 3) 
  [1] TRUE 

Our function, is.even(), could now be rewritten simply as follows:

  > is.even <- function(num){ 
  +   is.divisible.by(num, 2) 
  + } 

It is very common in R to want to apply a particular function to every element of a vector. Instead of using a loop to iterate over the elements of a vector, as we would do in many other languages, we use a function called sapply() to perform this. sapply() takes a vector and a function as its arguments. It then applies the function to every element and returns a vector of results. We can use sapply() in this manner to find out which digits in Jenny's phone number are even:

  > sapply(our.vect, is.even) 
  [1] FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE 

This worked great because sapply takes each element and uses it as the argument in is.even(), which takes only one argument. If you wanted to find the digits that are divisible by three, it would require a little bit more work.

One option is just to define a function,  is.divisible.by.three(), that takes only one argument and use this in sapply. The more common solution, however, is to define an unnamed function that does just that in the body of the sapply function call:

  > sapply(our.vect, function(num){is.divisible.by(num, 3)}) 
  [1]  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE 

Here, we essentially created a function that checks whether its argument is divisible by three, except we don't assign it to a variable and use it directly in the sapply body instead. These one-time-use unnamed functions are called anonymous functions or lambda functions. (The name comes from Alonzo Church's invention of the lambda calculus, if you were wondering.)

This is somewhat of an advanced usage of R, but it is very useful as it comes up very often in practice.

If we wanted to extract the digits in Jenny's phone number that are divisible by both, two and three, we can write it as follows:

  > where.even <- sapply(our.vect, is.even) 
  > where.div.3 <- sapply(our.vect, function(num){ 
  +   is.divisible.by(num, 3)}) 
  > # "&" is like the "&&" and operator but for vectors  
  > our.vect[where.even & where.div.3] 
  [1] 6 0 

Neat-O!

Note that if we wanted to be sticklers, we would have a clause in the function bodies to preclude a modulus computation, where the first number was smaller than the second. If we had, our function would not have erroneously indicated that 0 was divisible by two and three. I'm not a stickler, though, so the function will remain as is. Fixing this function is left as an exercise for the (stickler) reader.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime