# Control flow, loops, apply and functions

#### Ic3fr0g

#### 2018-02-25

# 1 Control Flow

If help is required for any of the following code and keywords type `?Control` in your console and refer to the vignette.

## 1.1 Inline ifelse

Most programming languages have `if` and `else` conditions that enable you to extend your workflow:

    # Usage:
    # ifelse(cond, if_true_expr, if_false_expr)

Here’s a trivial example using the `floor(...)` function:

    # Create a numeric
    x <- 4.321
    # Floor function gives an integer lesser than or equal to 'x'
    ifelse( floor(x) == 4, x + 2, x * 2)

    [1] 6.321

## 1.2 if and else

The more generic `if` and `else` conditional statements can execute compound statements:

    # Usage:
    # if(cond)    if_true_expr    else    if_false_expr

Here’s the same example from above with `ceiling(...)` instead of `floor(...)` function:

    # Ceiling function gives an integer greater than or equal to 'x'
    if (ceiling(x) == 4) {
        x + 2
    } else {
        x * 2
    }

    [1] 8.642

Here’s a `nested if-else` condition that checks whether a number is positive or negative and odd or even:

    # Reads an input
    num <- as.numeric(readline("Enter a number? "))
    999
    # Nested if-else
    if (num > 0) {
        cat("The number is greater than 0 ")
        if (num %% 2 == 0) {
            cat("and even")
        } else {
            cat("and odd")
        }
    } else if (num < 0) {
        cat("The number is less than 0 ")
        if (num %% 2 == 0) {
            cat("and even")
        } else {
            cat("and odd")
        }
    } else {
        cat("The number is 0 ")
    }

    The number is greater than 0 and odd

# 2 Loops

## 2.1 for

The most popular loop statement, `for`, uses iterators that may seem foreign to people from a Java or C++ background. Here’s the usage for `for`:

    # Usage:
    # for(var in seq) expr

Here’s a trivial example:

    # Prints 'Hello world!' 3 times
    for (i in c(1,2,3)) {
        print("Hello world!")
    }

    [1] "Hello world!"
    [1] "Hello world!"
    [1] "Hello world!"

Here’s another example using a iterator of a character vector:

    # Prints out every item in the character vector
    for (item in c("This","will","work")) {
        message(item)
    }

    This
    will
    work

Here’s how you iterate through columns in a dataframe:

    # Creates a dataframe
    df <- data.frame(x = c(1,2,3),
                     y = c("A","B","C"),
                     stringsAsFactors = FALSE)
    # Structure of columns in the dataframe
    for (col in df) {
        str(col)
    }

     num [1:3] 1 2 3
     chr [1:3] "A" "B" "C"

Here’s how you iterate through rows:

    # Concatenates the columns
    for (i in 1:nrow(df)) {
        row <- df[i,]
        message(row)
    }

    1A
    2B
    3C

## 2.2 Break and Next

This section talks about keywords that are specfic to loops. The keywords do not return anything but transfer the control within a loop. `break` stops the any further iterations of the loop:

    # Encountering a break
    for (i in 1:10) {
        if (i == 5) break
        else print(sprintf("Message %d",i))
    }

    [1] "Message 1"
    [1] "Message 2"
    [1] "Message 3"
    [1] "Message 4"

`next` skips the current iterations of the loop, if encountered:

    # Encountering a next
    for (i in 1:10) {
        if (i == 5) next
        else message(sprintf("Message %d",i))
    }

    Message 1
    Message 2
    Message 3
    Message 4
    Message 6
    Message 7
    Message 8
    Message 9
    Message 10

## 2.3 while-loop

A `while` loop is another form of loop. This is the general usage:

    # Usage:
    # while(cond) expr

Here’s a trivial example:

    # Create a variable
    x <- 0
    # Prints x for values less than or equal to 3
    while (x <= 3) {
        message(x)
        x <- x + 1
    }

    0
    1
    2
    3

## 2.4 repeat-loop

The `repeat` construct within R is rather odd but would still be familiar in some form to most programmers:

    # Usage:
    # repeat expr break next

It is imperative for the `repeat` loop to contain an update statement and a `break` (optionally, a `next` statement). Let’s explore an example:

    # Create a variable
    x <- 0
    # repeat-loop
    repeat {
        x <- x + 1                    # Update x
        if (x == 10) {
            break                       # Break if this condition encountered
        } else if (x %% 2 == 1) {
            message(0)
        } else {
            message(x)
        }
    }

    0
    2
    0
    4
    0
    6
    0
    8
    0

# 3 Functions

## 3.1 Syntax

Functions can be built-in or user-defined. In this section we explore the syntax for user-defined functions:

    # Usage:
    # function-name <- function(x) {does-something-here}
    # Function to calculate the sum of first n numbers
    first_n <- function(n) {
        sum_x = 0
        for (x in 1:n) {
            sum_x = sum_x + x
        }
        sum_x
    }
    # Function call
    first_n(10)

    [1] 55

## 3.2 Recall

`Recall(...)` enables us to create recursive functions:

    # A recursive function
    sum_of_first_n <- function(n) {
        if (n == 1) 1 else n + Recall(n - 1)
    }
    # Function call
    sum_of_first_n(10)

    [1] 55

# 4 Apply

## 4.1 apply

Very often we have to apply functions on dataframes and other types of data structures. The `apply(...)` function let’s us iteratively access the elements within a datatype and then perform some function on it. Let’s explore an example wherein we have to fetch the marks obtained by the students for a 50 mark exam:

    # Usage:
    # apply(X, MARGIN, FUN)
    # Create a dataframe
    marks_percentage <- data.frame(names = c("Tom", "Dick", "John", "Abby"),
                                   math = c(0.88, 0.81, 0.67, 0.95),
                                   science = c(0.88, 0.79, 0.57, 0.89))
    # apply function
    marks_obtained <- apply(marks_percentage[,2:3],
                            2,
                            function(x) {
                                x * 50
                            })
    marks_obtained

         math science
    [1,] 44.0    44.0
    [2,] 40.5    39.5
    [3,] 33.5    28.5
    [4,] 47.5    44.5