{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "jRNjXbUlTQPB" }, "source": [ "# Control Structures\n", "\n", "This lesson will cover how R code uses loops and conditionals, just like Python." ] }, { "cell_type": "markdown", "metadata": { "id": "m7votYy_Yh7f" }, "source": [ "## Conditions\n", "\n", "R uses a model similar to Python for control structures. The `if` and `else if` statements require a logical test that results in `TRUE` or `FALSE`, while `else` acts as a catch-all with no condition.\n", "\n", "In terms of syntax, the main differences between R and Python are:\n", "\n", "- Conditions are enclosed in parentheses.\n", "- There is no `:` after the condition statement to indicate the code block to execute.\n", "- The code block to run is enclosed in `{}`, rather than being indicated by indentation.\n", "- `elif` in Python is called `else if` in R.\n", "\n", "On the other hand, comparison operators in R are the following:\n", "\n", "| Operator | Name | Example |\n", "|---|---|---|\n", "| `==` | Equals | `x == y` |\n", "| `!=` | Not equals | `y != x` |\n", "| `>` | Greater than | `x > y` |\n", "| `<` | Less than | `y < x` |\n", "| `>=` | Greater than or equal to | `x >= y` |\n", "| `<=` | Less than or equal to | `y <= x` |\n", "\n", "Let's have a look at different examples:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "id": "yPHhbOulYmBw" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] \"y is greater than x\"\n" ] } ], "source": [ "x <- 14\n", "y <- 120\n", "\n", "if (y > x) {\n", " print(\"y is greater than x\")\n", "}" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "id": "4_MdL-xUZH5A" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] \"x and y are equal\"\n" ] } ], "source": [ "x <- 33\n", "y <- 33\n", "\n", "if (y > x) {\n", " print(\"y is greater than x\")\n", "} else if (x == y) {\n", " print(\"x and y are equal\")\n", "}" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "id": "XDnNHcz4ZWWX" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] \"x is greater than y\"\n" ] } ], "source": [ "x <- 120\n", "y <- 44\n", "\n", "if (y > x) {\n", " print(\"y is greater than x\")\n", "} else if (x == y) {\n", " print(\"x and y are equal\")\n", "} else {\n", " print(\"x is greater than y\")\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "R provides an `ifelse` function, which is very useful for converting data into boolean values." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
  1. 'EVEN'
  2. 'ODD'
  3. 'ODD'
  4. 'EVEN'
  5. 'EVEN'
  6. 'ODD'
  7. 'ODD'
\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item 'EVEN'\n", "\\item 'ODD'\n", "\\item 'ODD'\n", "\\item 'EVEN'\n", "\\item 'EVEN'\n", "\\item 'ODD'\n", "\\item 'ODD'\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. 'EVEN'\n", "2. 'ODD'\n", "3. 'ODD'\n", "4. 'EVEN'\n", "5. 'EVEN'\n", "6. 'ODD'\n", "7. 'ODD'\n", "\n", "\n" ], "text/plain": [ "[1] \"EVEN\" \"ODD\" \"ODD\" \"EVEN\" \"EVEN\" \"ODD\" \"ODD\" " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# input vector\n", "x <- c(12, 9, 23, 14, 20, 1, 5)\n", "\n", "# ifelse() function to determine odd/even numbers\n", "ifelse(x %% 2 == 0, \"EVEN\", \"ODD\")" ] }, { "cell_type": "markdown", "metadata": { "id": "BqwD2Nj8TS5E" }, "source": [ "## Loops\n", "\n", "\n", "### `while` loops\n", "\n", "\n", "The syntax for `while` loops in R is the following:\n", "\n", "```\n", "while ( CONDITION ) {\n", "STATEMENT1\n", "STATEMENT2\n", "ETC\n", "}\n", "```\n", "\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] 17\n", "[1] 34\n", "[1] 51\n", "[1] 68\n", "[1] 85\n", "[1] 102\n", "[1] \"I exited the loop, yeah!\"\n" ] } ], "source": [ "x <- 0\n", "while ( x < 100 ) {\n", " x <- x + 17 # Indentation is not required; it’s used here only to improve readability.\n", " print( x )\n", "}\n", "print(\"I exited the loop, yeah!\")" ] }, { "cell_type": "markdown", "metadata": { "id": "j8h-_W_B0hHR" }, "source": [ "### `break` - exit the loop\n", "\n", "As in Python, it stops the loop entirely." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "id": "CSLP66hf00F6" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] 1\n", "[1] 2\n", "[1] 3\n", "[1] 4\n", "[1] \"I'm all done!\"\n" ] } ], "source": [ "# BREAK\n", "\n", "i <- 1\n", "while (i < 9) {\n", " print(i)\n", " i <- i + 1\n", " if (i == 5) {\n", " print(\"I'm all done!\")\n", " break\n", " }\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `next` - stop the current iteration\n", "\n", "It skips an interation of the loop and moves on to the next step in logic. In Python this corresponds to the `continue` keyword." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] 1\n", "[1] 2\n", "[1] 3\n", "[1] 4\n", "[1] \"Here is where I pass\"\n", "[1] 6\n", "[1] 7\n", "[1] 8\n" ] } ], "source": [ "# NEXT\n", "i <- 0\n", "while (i < 8) {\n", " i <- i + 1\n", " if (i == 5) {\n", " print(\"Here is where I pass\")\n", " next\n", " }\n", " print(i)\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `for` loops" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The syntax for `for` loops in R is the following:\n", "\n", "```\n", "for ( VAR in iterable ) {\n", "STATEMENT1\n", "STATEMENT2\n", "ETC\n", "}\n", "```\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In R, an iterable can be a numeric count or range (using `:` or `seq`), a series of elements in a list or vector, or a numeric range/limit applied to a vector." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "id": "Y60RH0l1TZFz" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] 1\n", "[1] 2\n", "[1] 3\n", "[1] 4\n", "[1] 5\n", "[1] 6\n", "[1] 7\n", "[1] 8\n", "[1] 9\n", "[1] 10\n" ] } ], "source": [ "# loops 10x, counting 1-10.\n", "for(ii in 1:10) {\n", " print(ii)\n", "}" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "id": "vUA8aXUOTeet" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] \"a\"\n", "[1] \"b\"\n", "[1] \"x\"\n", "[1] \"y\"\n", "[1] \"z\"\n" ] } ], "source": [ "# loops once for each item in a vector\n", "x <- c(\"a\", \"b\", \"x\", \"y\", \"z\")\n", "for(ii in x) {\n", " print(ii)\n", "}" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "id": "pAfeV-G2TyrQ" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] \"a\"\n", "[1] \"b\"\n", "[1] \"x\"\n" ] } ], "source": [ "# loops in a range of items (3x) mapped against a vector.\n", "# therefore loops 3x total against a, b, and x.\n", "\n", "x <- c(\"a\", \"b\", \"x\", \"y\", \"z\")\n", "\n", "for(ii in 1:3) {\n", " print(x[ii])\n", "}" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] 5\n", "[1] 5\n", "[1] 5\n", "[1] 5\n", "[1] 5\n", "[1] 5\n", "[1] 5\n", "[1] 5\n", "[1] 5\n", "[1] 5\n" ] } ], "source": [ "# What about iterating across a range, but only at certain intervals?\n", "# Use a sequence from 1-30 but count in intervals of 3\n", "\n", "for(i in seq(1, 30, 3)) {\n", " print(ii)\n", "}" ] }, { "cell_type": "markdown", "metadata": { "id": "A57JqVZrUANj" }, "source": [ "## `seq_along()` \n", "\n", "This function has a similar purpose to Python's `enumerate`: it generates an integer sequence based on the length of an object." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "id": "x9SW3BhsUHPZ" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] 1\n", "[1] \"a\"\n", "[1] 2\n", "[1] \"b\"\n", "[1] 3\n", "[1] \"x\"\n", "[1] 4\n", "[1] \"y\"\n", "[1] 5\n", "[1] \"z\"\n" ] } ], "source": [ "x <- c(\"a\", \"b\", \"x\", \"y\", \"z\")\n", "\n", "for(ii in seq_along(x)) {\n", " print(ii) # the integer of the vector item index\n", " print(x[ii]) # the actual value of the vector item\n", "}" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "id": "vigE4HTVUTuI" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] \"a\"\n", "[1] \"b\"\n", "[1] \"x\"\n", "[1] \"y\"\n", "[1] \"z\"\n" ] } ], "source": [ "# compare to this for-loop that skips integer/indexing and simply takes each value of the vector in sequence\n", "for(letter in x) {\n", " print(letter)\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Practice exercises" ] }, { "cell_type": "markdown", "metadata": { "id": "svSHPFyNbcE8" }, "source": [ "```{exercise}\n", ":label: Rloops1\n", "\n", "1- Write a piece of code that prints \"x is an even number\" if a variable x (which you define) is even; otherwise, print “x is an odd number.” Test your code by setting x to both an odd and an even number. (Hint: You may find the modulus operator helpful here.)\n", "\n", "Extra challenge: Can you modify the message to include the actual value of x in the output?\n", "\n", "```" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "# Your answers here" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{exercise}\n", ":label: Rloops2\n", "\n", "2- Create a variable named x and assign it an initial value. Then, create a loop that iterates over a range from 1 to 10. In each iteration, update the value of x by adding the current number in the loop to x.\n", "\n", "```" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "# Your answers here" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{exercise}\n", ":label: Rloops3\n", "\n", "3- Write a piece of code that calculates the sum of all integers from 0 up to a specified number. Use a while loop to calculate the sum. Then, test your result by comparing it with the output of the sum function applied to a sequence from 1 to the specified number.\n", "```" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [], "source": [ "# Your answers here" ] } ], "metadata": { "colab": { "authorship_tag": "ABX9TyMw2sAoclMrn8xGLBPcBq4A", "include_colab_link": true, "provenance": [] }, "kernelspec": { "display_name": "R", "language": "R", "name": "ir" }, "language_info": { "codemirror_mode": "r", "file_extension": ".r", "mimetype": "text/x-r-source", "name": "R", "pygments_lexer": "r", "version": "4.4.1" } }, "nbformat": 4, "nbformat_minor": 4 }