Ch. 1 - Conditionals and Control Flow

Relational Operators

[Video]

Equality ==

TRUE == TRUE
## [1] TRUE
TRUE == FALSE
## [1] FALSE

Inequality !=

"hello" != "goodbye"
## [1] TRUE

< and >

3 < 5
## [1] TRUE
# Alphabetical order
"Zulu" > "Alfa"
## [1] TRUE
# TRUE coerces to 1
# FALSE corces to 0
TRUE < FALSE
## [1] FALSE

<= and >=

5 >= 3
## [1] TRUE
3 >= 3
## [1] TRUE

Relational Operators & Vectors

linkedin <- c(16, 9, 13, 5, 2, 17, 14)
linkedin
## [1] 16  9 13  5  2 17 14
linkedin > 10
## [1]  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE

Equality

# Comparison of logicals
TRUE == FALSE
## [1] FALSE
# Comparison of numerics
(-6 * 14) != (17 - 101)
## [1] FALSE
# Comparison of character strings
"useR" == "user"
## [1] FALSE
# Compare a logical with a numeric
TRUE == 1
## [1] TRUE

Greater and less than

# Comparison of numerics
(-6 * 5 + 2) >= (-10 +1)
## [1] FALSE
# Comparison of character strings
"raining" <= "raining dogs"
## [1] TRUE
# Comparison of logicals
TRUE > FALSE
## [1] TRUE

Compare vectors

# The linkedin and facebook vectors have already been created for you
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
facebook <- c(17, 7, 5, 16, 8, 13, 14)

# Popular days
linkedin > 15
## [1]  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE
# Quiet days
linkedin <= 5
## [1] FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE
# LinkedIn more popular than Facebook
linkedin > facebook
## [1] FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE

Compare matrices

# The social data has been created for you
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
facebook <- c(17, 7, 5, 16, 8, 13, 14)
views <- matrix(c(linkedin, facebook), nrow = 2, byrow = TRUE)

# When does views equal 13?
views == 13
##       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]
## [1,] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
## [2,] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
# When is views less than or equal to 14?
views <= 14
##       [,1] [,2] [,3]  [,4] [,5]  [,6] [,7]
## [1,] FALSE TRUE TRUE  TRUE TRUE FALSE TRUE
## [2,] FALSE TRUE TRUE FALSE TRUE  TRUE TRUE

Logical Operators

[Video]

AND operator “&”

TRUE & TRUE
## [1] TRUE
TRUE & FALSE
## [1] FALSE
FALSE & TRUE
## [1] FALSE
FALSE & FALSE
## [1] FALSE

OR operator “|”

TRUE | TRUE
## [1] TRUE
TRUE | FALSE
## [1] TRUE
FALSE | TRUE
## [1] TRUE
FALSE | FALSE
## [1] FALSE

NOT operator “!”

!TRUE
## [1] FALSE
!FALSE
## [1] TRUE

Logical Operators & Vectors

c(TRUE, TRUE, FALSE) & c(TRUE, FALSE, FALSE)
## [1]  TRUE FALSE FALSE
c(TRUE, TRUE, FALSE) | c(TRUE, FALSE, FALSE)
## [1]  TRUE  TRUE FALSE
!c(TRUE, TRUE, FALSE)
## [1] FALSE FALSE  TRUE

“&” vs “&&”, “|” vs “||”

c(TRUE, TRUE, FALSE) & c(TRUE, FALSE, FALSE)
## [1]  TRUE FALSE FALSE
# Only examines first element of each vector
c(TRUE, TRUE, FALSE) && c(TRUE, FALSE, FALSE)
## [1] TRUE
# Only examines first element of each vector
c(TRUE, TRUE, FALSE) || c(TRUE, FALSE, FALSE)
## [1] TRUE

& and |

# The linkedin and last variable are already defined for you
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
last <- tail(linkedin, 1)

# Is last under 5 or above 10?
last < 5 | last > 10
## [1] TRUE
# Is last between 15 (exclusive) and 20 (inclusive)?
15 < last & last <= 20 
## [1] FALSE

& and | (2)

# The social data (linkedin, facebook, views) has been created for you

# linkedin exceeds 10 but facebook below 10
linkedin > 10 & facebook < 10
## [1] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
# When were one or both visited at least 12 times?
linkedin >=12 | facebook >= 12
## [1]  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE
# When is views between 11 (exclusive) and 14 (inclusive)?
views > 11 & views <= 14
##       [,1]  [,2]  [,3]  [,4]  [,5]  [,6] [,7]
## [1,] FALSE FALSE  TRUE FALSE FALSE FALSE TRUE
## [2,] FALSE FALSE FALSE FALSE FALSE  TRUE TRUE

Reverse the result: !

On top of the & and | operators, you also learned about the ! operator, which negates a logical value. To refresh your memory, here are some R expressions that use !. They all evaluate to FALSE:

!TRUE
## [1] FALSE
!(5 > 3)
## [1] FALSE
!!FALSE
## [1] FALSE

What would the following set of R expressions return?

x <- 5
y <- 7
!(!(x < 4) & !!!(y > 12))
## [1] FALSE
  • TRUE
  • [*] FALSE
  • Running this piece of code would throw an error.

Blend it all together

# li_df is pre-loaded in your workspace

# Select the second column, named day2, from li_df: second
second <- li_df[, 2]

# Build a logical vector, TRUE if value in second is extreme: extremes
extremes <- second > 25 | second < 5

# Count the number of TRUEs in extremes
sum(extremes)
## [1] 16

Conditional Statements

[Video]

if statement

# if(condition) {
#   expr
# }
x <- -3
if(x < 0) {
  print("x is a negative numnber")
}
## [1] "x is a negative numnber"

else statement

# if(condition) {
#   expr1
# } else {
#   expr2
# }
x <- 5
if(x < 0) {
  print("x is a negative numnber")
} else {
  print("x is either a positive number or zero")
}
## [1] "x is either a positive number or zero"

else if statement

# if(condition1) {
#   expr1
# } else if(condition2) {
#   expr2
# } else {
#   expr3
# }

The if statement

# Variables related to your last day of recordings
medium <- "LinkedIn"
num_views <- 14

# Examine the if statement for medium
if (medium == "LinkedIn") {
  print("Showing LinkedIn information")
}
## [1] "Showing LinkedIn information"
# Write the if statement for num_views
if(num_views > 15) {
  print("You are popular!")
}

Add an else

# Variables related to your last day of recordings
medium <- "LinkedIn"
num_views <- 14

# Control structure for medium
if (medium == "LinkedIn") {
  print("Showing LinkedIn information")
} else {
  print("Unknown medium")
}
## [1] "Showing LinkedIn information"
# Control structure for num_views
if (num_views > 15) {
  print("You're popular!")
} else {
  print("Try to be more visible!")
}
## [1] "Try to be more visible!"

Customize further: else if

# Variables related to your last day of recordings
medium <- "LinkedIn"
num_views <- 14

# Control structure for medium
if (medium == "LinkedIn") {
  print("Showing LinkedIn information")
} else if (medium == "Facebook") {
  # Add code to print correct string when condition is TRUE
  print("Showing Facebook information")
} else {
  print("Unknown medium")
}
## [1] "Showing LinkedIn information"
# Control structure for num_views
if (num_views > 15) {
  print("You're popular!")
} else if (num_views <= 15 & num_views > 10) {
  # Add code to print correct string when condition is TRUE
  print("Your number of views is average")
} else {
  print("Try to be more visible!")
}
## [1] "Your number of views is average"

Else if 2.0

You can do anything you want inside if-else constructs. You can even put in another set of conditional statements. Examine the following code chunk:

# if (number < 10) {
#   if (number < 5) {
#     result <- "extra small"
#   } else {
#     result <- "small"
#   }
# } else if (number < 100) {
#   result <- "medium"
# } else {
#   result <- "large"
# }
# print(result)

Have a look at the following statements:

  1. If number is set to 6, “small” gets printed to the console.
  2. If number is set to 100, R prints out “medium”.
  3. If number is set to 4, “extra small” gets printed out to the console.
  4. If number is set to 2500, R will generate an error, as result will not be defined.

Select the option that lists all the true statements.

  • 2 and 4
  • 1 and 4
  • [*] 1 and 3
  • 2 and 3

Take control!

# Variables related to your last day of recordings
li <- 15
fb <- 9

# Code the control-flow construct
if (li >= 15 & fb >= 15) {
  sms <- 2 * (li + fb)
} else if(li < 10 & fb < 10) {
  sms <- 0.5 * (li + fb)
} else {
  sms <- li + fb
}

# Print the resulting sms to the console
sms
## [1] 24

Ch. 2 - Loops

While loop

[Video]

ctr <- 1
while(ctr <= 7) {
  print(paste("ctr is set to", ctr))
  ctr <- ctr + 1
}
## [1] "ctr is set to 1"
## [1] "ctr is set to 2"
## [1] "ctr is set to 3"
## [1] "ctr is set to 4"
## [1] "ctr is set to 5"
## [1] "ctr is set to 6"
## [1] "ctr is set to 7"
ctr
## [1] 8
ctr <- 1
while(ctr <= 7) {
  # Break if ctr is divisible by 5
  if(ctr %% 5 == 0) {
    break
  }
  print(paste("ctr is set to", ctr))
  ctr <- ctr + 1
}
## [1] "ctr is set to 1"
## [1] "ctr is set to 2"
## [1] "ctr is set to 3"
## [1] "ctr is set to 4"
ctr
## [1] 5

Write a while loop

# Initialize the speed variable
speed <- 64

# Code the while loop
while (speed > 30) {
  print("Slow down!")
  speed <- speed - 7
}
## [1] "Slow down!"
## [1] "Slow down!"
## [1] "Slow down!"
## [1] "Slow down!"
## [1] "Slow down!"
# Print out the speed variable
speed
## [1] 29

Throw in more conditionals

# Initialize the speed variable
speed <- 64

# Extend/adapt the while loop
while (speed > 30) {
  print(paste("Your speed is",speed))
  if(speed > 48) {
    print("Slow down big time!")
    speed <- speed - 11
  } else {
    print("Slow down!")
    speed <- speed - 6
  }
}
## [1] "Your speed is 64"
## [1] "Slow down big time!"
## [1] "Your speed is 53"
## [1] "Slow down big time!"
## [1] "Your speed is 42"
## [1] "Slow down!"
## [1] "Your speed is 36"
## [1] "Slow down!"

Stop the while loop: break

# Initialize the speed variable
speed <- 88

while (speed > 30) {
  print(paste("Your speed is", speed))
  
  # Break the while loop when speed exceeds 80
  if(speed > 80) {
    break
  }
  
  if (speed > 48) {
    print("Slow down big time!")
    speed <- speed - 11
  } else {
    print("Slow down!")
    speed <- speed - 6
  }
}
## [1] "Your speed is 88"

Build a while loop from scratch

# Initialize i as 1 
i <- 1

# Code the while loop
while (i <= 10) {
  print(3 * i)
  if ((i * 3) %% 8 == 0) {
    break
  }
  i <- i + 1
}
## [1] 3
## [1] 6
## [1] 9
## [1] 12
## [1] 15
## [1] 18
## [1] 21
## [1] 24

For loop

[Video]

for loop

cities <- c("New York", "Paris", "London", "Tokyo", "Rio de Janeiro", "Cape Town") # Vector
for(city in cities) {
  print(city)
}
## [1] "New York"
## [1] "Paris"
## [1] "London"
## [1] "Tokyo"
## [1] "Rio de Janeiro"
## [1] "Cape Town"

for loop over list

cities <- list("New York", "Paris", "London", "Tokyo", "Rio de Janeiro", "Cape Town")
for(city in cities) {
  print(city)
}
## [1] "New York"
## [1] "Paris"
## [1] "London"
## [1] "Tokyo"
## [1] "Rio de Janeiro"
## [1] "Cape Town"

break statement

for(city in cities) {
  if(nchar(city) == 6) {
    break
  }
  print(city)
}
## [1] "New York"
## [1] "Paris"

next statement

for(city in cities) {
  if(nchar(city) == 6) {
    next
  }
  print(city)
}
## [1] "New York"
## [1] "Paris"
## [1] "Tokyo"
## [1] "Rio de Janeiro"
## [1] "Cape Town"

for loop: v2

cities <- c("New York", "Paris", "London", "Tokyo", "Rio de Janeiro", "Cape Town")
for(i in 1:length(cities)) {
  print(paste(cities[i], "in on position", i, "in the cities vector."))
}
## [1] "New York in on position 1 in the cities vector."
## [1] "Paris in on position 2 in the cities vector."
## [1] "London in on position 3 in the cities vector."
## [1] "Tokyo in on position 4 in the cities vector."
## [1] "Rio de Janeiro in on position 5 in the cities vector."
## [1] "Cape Town in on position 6 in the cities vector."

Loop over a vector

# The linkedin vector has already been defined for you
linkedin <- c(16, 9, 13, 5, 2, 17, 14)

# Loop version 1
for(l in linkedin) {
  print(l)
}
## [1] 16
## [1] 9
## [1] 13
## [1] 5
## [1] 2
## [1] 17
## [1] 14
# Loop version 2
for(i in 1:length(linkedin)) {
  print(linkedin[i])
}
## [1] 16
## [1] 9
## [1] 13
## [1] 5
## [1] 2
## [1] 17
## [1] 14

Loop over a list

# The nyc list is already specified
nyc <- list(pop = 8405837, 
            boroughs = c("Manhattan", "Bronx", "Brooklyn", "Queens", "Staten Island"), 
            capital = FALSE)

# Loop version 1
for(info in nyc) {
  print(info)
}
## [1] 8405837
## [1] "Manhattan"     "Bronx"         "Brooklyn"      "Queens"       
## [5] "Staten Island"
## [1] FALSE
# Loop version 2
for(i in 1:length(nyc)) {
  print(nyc[[i]])
}
## [1] 8405837
## [1] "Manhattan"     "Bronx"         "Brooklyn"      "Queens"       
## [5] "Staten Island"
## [1] FALSE

Loop over a matrix

# The tic-tac-toe matrix ttt has already been defined for you

# define the double for loop
for (i in 1:nrow(ttt)) {
  for (j in 1:ncol(ttt)) {
    print(paste("On row", i, "and column", j, "the board contains", ttt[i, j]))
  }
}
## [1] "On row 1 and column 1 the board contains O"
## [1] "On row 1 and column 2 the board contains NA"
## [1] "On row 1 and column 3 the board contains X"
## [1] "On row 2 and column 1 the board contains NA"
## [1] "On row 2 and column 2 the board contains O"
## [1] "On row 2 and column 3 the board contains 0"
## [1] "On row 3 and column 1 the board contains X"
## [1] "On row 3 and column 2 the board contains NA"
## [1] "On row 3 and column 3 the board contains X"

Mix it up with control flow

# The linkedin vector has already been defined for you
linkedin <- c(16, 9, 13, 5, 2, 17, 14)

# Code the for loop with conditionals
for (li in linkedin) {
  if (li > 10) {
    print("You're popular!")
  } else {
    print("Be more visible!")
  }
  print(li)
}
## [1] "You're popular!"
## [1] 16
## [1] "Be more visible!"
## [1] 9
## [1] "You're popular!"
## [1] 13
## [1] "Be more visible!"
## [1] 5
## [1] "Be more visible!"
## [1] 2
## [1] "You're popular!"
## [1] 17
## [1] "You're popular!"
## [1] 14

Next, you break it

# The linkedin vector has already been defined for you
linkedin <- c(16, 9, 13, 5, 2, 17, 14)

# Adapt/extend the for loop
for (li in linkedin) {
  if (li > 10) {
    print("You're popular!")
  } else {
    print("Be more visible!")
  }
  
  # Add if statement with break
  if(li > 16) {
    print("This is ridiculous, I'm outta here!")
    break
  }
  
  # Add if statement with next
  if(li < 5) {
    print("This is too embarrassing!")
    next
  }
  
  print(li)
}
## [1] "You're popular!"
## [1] 16
## [1] "Be more visible!"
## [1] 9
## [1] "You're popular!"
## [1] 13
## [1] "Be more visible!"
## [1] 5
## [1] "Be more visible!"
## [1] "This is too embarrassing!"
## [1] "You're popular!"
## [1] "This is ridiculous, I'm outta here!"

Build a for loop from scratch

# Pre-defined variables
rquote <- "r's internals are irrefutably intriguing"
chars <- strsplit(rquote, split = "")[[1]]

# Initialize rcount
rcount <- 0

# Finish the for loop
for (char in chars) {
  if(char == "r") {
    rcount <- rcount + 1
  }
  if(char == "u") {
    break
  }
  
}

# Print out rcount
rcount
## [1] 5

Ch. 3 - Functions

Introduction to Functions

[Video]

Function documentation

# Consult the documentation on the mean() function
help(mean)

# Inspect the arguments of the mean() function
args(mean)
## function (x, ...) 
## NULL

Use a function

# The linkedin and facebook vectors have already been created for you
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
facebook <- c(17, 7, 5, 16, 8, 13, 14)

# Calculate average number of views
avg_li <- mean(linkedin)
avg_fb <- mean(facebook)

# Inspect avg_li and avg_fb
avg_li
## [1] 10.85714
avg_fb
## [1] 11.42857

Use a function (2)

# The linkedin and facebook vectors have already been created for you
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
facebook <- c(17, 7, 5, 16, 8, 13, 14)

# Calculate the mean of the sum
avg_sum <- mean(linkedin + facebook)

# Calculate the trimmed mean of the sum
avg_sum_trimmed <- mean(linkedin + facebook, 0.2)

# Inspect both new variables
avg_sum
## [1] 22.28571
avg_sum_trimmed
## [1] 22.6

Use a function (3)

# The linkedin and facebook vectors have already been created for you
linkedin <- c(16, 9, 13, 5, NA, 17, 14)
facebook <- c(17, NA, 5, 16, 8, 13, 14)

# Basic average of linkedin
mean(linkedin)
## [1] NA
# Advanced average of linkedin
mean(linkedin, na.rm = TRUE)
## [1] 12.33333

Functions inside functions

# The linkedin and facebook vectors have already been created for you
linkedin <- c(16, 9, 13, 5, NA, 17, 14)
facebook <- c(17, NA, 5, 16, 8, 13, 14)

# Calculate the mean absolute deviation
mean(abs(linkedin - facebook), na.rm = TRUE)
## [1] 4.8

Required, or optional?

By now, you will probably have a good understanding of the difference between required and optional arguments. Let’s refresh this difference by having one last look at the mean() function:

# mean(x, trim = 0, na.rm = FALSE, ...)

x is required; if you do not specify it, R will throw an error. trim and na.rm are optional arguments: they have a default value which is used if the arguments are not explicitly specified.

Which of the following statements about the read.table() function are true?

  1. header, sep and quote are all optional arguments.
  2. row.names and fileEncoding don’t have default values.
  3. read.table(“myfile.txt”, “-”, TRUE) will throw an error.
  4. read.table(“myfile.txt”, sep = “-”, header = TRUE) will throw an error.
help(read.table)
args(read.table)
## function (file, header = FALSE, sep = "", quote = "\"'", dec = ".", 
##     numerals = c("allow.loss", "warn.loss", "no.loss"), row.names, 
##     col.names, as.is = !stringsAsFactors, na.strings = "NA", 
##     colClasses = NA, nrows = -1, skip = 0, check.names = TRUE, 
##     fill = !blank.lines.skip, strip.white = FALSE, blank.lines.skip = TRUE, 
##     comment.char = "#", allowEscapes = FALSE, flush = FALSE, 
##     stringsAsFactors = default.stringsAsFactors(), fileEncoding = "", 
##     encoding = "unknown", text, skipNul = FALSE) 
## NULL
  • [*] 1 and 2
  • 2 and 4
  • 1, 2, and 3
  • 1, 2, and 4

Writing Functions

[Video]

The triple function

triple <- function(x) {
  3 * x
}
triple(6)
## [1] 18

return()

triple <- function(x) {
  y <- 3 * x
  return(y)
}
triple(6)
## [1] 18

The math_magic() function

math_magic <- function(a, b) {
  a * b + a / b
}
math_magic(4, 2)
## [1] 10
# math_magic(4)

# Error in math_magic(4) : argument "b" is missing, with no default

Optional argument

math_magic <- function(a, b = 1) {
  a * b + a / b
}
math_magic(4)
## [1] 8
math_magic(4, 0)
## [1] Inf

Use return()

math_magic <- function(a, b = 1) {
  if(b == 0) {
    return(0)
  }
  a * b + a / b
}
math_magic(4, 0)
## [1] 0

Write your own function

# Create a function pow_two()
pow_two <- function(a) {
  return(a ^ 2)
}

# Use the function
pow_two(12)
## [1] 144
# Create a function sum_abs()
sum_abs <- function(a, b) {
  return(abs(a) + abs(b))
}

# Use the function
sum_abs(-2, 3)
## [1] 5

Write your own function (2)

# Define the function hello()
hello <- function() {
  print("Hi there!")
  return(TRUE)
}

# Call the function hello()
hello()
## [1] "Hi there!"
## [1] TRUE

Write your own function (3)

# Finish the pow_two() function
pow_two <- function(x, print_info = TRUE) {
  y <- x ^ 2
  if(print_info == TRUE) {
    print(paste(x, "to the power two equals", y))
  }
  return(y)
}

Function scoping

An issue that Filip did not discuss in the video is function scoping. It implies that variables that are defined inside a function are not accessible outside that function. Try running the following code and see if you understand the results:

# pow_two <- function(x) {
#   y <- x ^ 2
#   return(y)
# }
# pow_two(4)
# y
# x

y was defined inside the pow_two() function and therefore it is not accessible outside of that function. This is also true for the function’s arguments of course - x in this case.

Which statement is correct about the following chunk of code? The function two_dice() is already available in the workspace.

# two_dice <- function() {
#   possibilities <- 1:6
#   dice1 <- sample(possibilities, size = 1)
#   dice2 <- sample(possibilities, size = 1)
#   dice1 + dice2
# }
  • Executing two_dice() causes an error.
  • Executing res <- two_dice() makes the contents of dice1 and dice2 available outside the function.
  • [*] Whatever the way of calling the two_dice() function, R won’t have access to dice1 and dice2 outside the function.

R passes arguments by value

The title gives it away already: R passes arguments by value. What does this mean? Simply put, it means that an R function cannot change the variable that you input to that function. Let’s look at a simple example (try it in the console):

# triple <- function(x) {
#   x <- 3*x
#   x
# }
# a <- 5
# triple(a)
# a

Inside the triple() function, the argument x gets overwritten with its value times three. Afterwards this new x is returned. If you call this function with a variable a set equal to 5, you obtain 15. But did the value of a change? If R were to pass a to triple() by reference, the override of the x inside the function would ripple through to the variable a, outside the function. However, R passes by value, so the R objects you pass to a function can never change unless you do an explicit assignment. a remains equal to 5, even after calling triple(a).

Can you tell which one of the following statements is false about the following piece of code?

increment <- function(x, inc = 1) {
  x <- x + inc
  x
}
count <- 5
a <- increment(count, 2)
b <- increment(count)
count <- increment(count, 2)
  • a and b equal 7 and 6 respectively after executing this code block.
  • After the first call of increment(), where a is defined, a equals 7 and count equals 5.
  • [*] In the end, count will equal 10.
  • In the last expression, the value of count was actually changed because of the explicit assignment.

R you functional?

# The linkedin and facebook vectors have already been created for you

# Define the interpret function
interpret <- function(num_views) {
  if (num_views > 15) {
    print("You're popular!")
    return(num_views)
  } else {
    print("Try to be more visible!")
    return(0)
  }
}

# Call the interpret function twice
interpret(linkedin[1])
## [1] "You're popular!"
## [1] 16
interpret(facebook[2])
## [1] "Try to be more visible!"
## [1] 0

R you functional? (2)

R Packages

Load an R Package

Different ways to load a package


Ch. 4 - The apply family

lapply

Use lapply with a built-in R function

Use lapply with your own function

lapply and anonymous functions

Use lapply with additional arguments

Apply functions that return NULL

sapply

How to use sapply

sapply with your own function

sapply with function returning vector

sapply can’t simplify, now what?

sapply with functions that return NULL

Reverse engineering sapply

vapply

Use vapply

Use vapply (2)

From sapply to vapply


Ch. 5 - Utilities

Useful Functions

Mathematical utilities

Find the error

Data Utilities

Find the error (2)

Beat Gauss using R

Regular Expressions

grepl & grep

grepl & grep (2)

sub & gsub

sub & gsub (2)

Times & Dates

Right here, right now

Create and format dates

Create and format times

Calculations with Dates

Calculations with Times

Time is of the essence


About Michael Mallari

Michael is a hybrid thinker and doer—a byproduct of being a StrengthsFinder “Learner” over time. With 20+ years of engineering, design, and product experience, he helps organizations identify market needs, mobilize internal and external resources, and deliver delightful digital customer experiences that align with business goals. He has been entrusted with problem-solving for brands—ranging from Fortune 500 companies to early-stage startups to not-for-profit organizations.

Michael earned his BS in Computer Science from New York Institute of Technology and his MBA from the University of Maryland, College Park. He is also a candidate to receive his MS in Applied Analytics from Columbia University.

LinkedIn | Twitter | www.michaelmallari.com/data | www.columbia.edu/~mm5470