R Basics (Syntax, Types, Control Flow)

Context: FIT1043_MOC Β· the language fundamentals of R Β· assignment, types, and control flow before vectors/data frames Problem it solves: write and read basic R β€” assign variables, check/convert types, and branch/loop.

Quick Revision

  • 🎯 Trigger: any R snippet βž” assign with the arrow operator, inspect type with class(), branch/loop with if/for/while.
  • ⚑ Key Constraint: R’s assignment is <- (not =), and a bare number like 10 is numeric, not integer β€” use as.integer() to force it.

πŸ”§ Minimal Working Example

A <- 10            # assign (preferred operator)
5 * A + 6          # [1] 56
y <- 8
class(y)           # [1] "numeric"
is.integer(y)      # [1] FALSE
as.character(y)    # [1] "8"   (type conversion)

Expected output: A holds 10; class(y) is "numeric"; conversion returns the string "8".

  • Assignment βž” x <- value (the R idiom); expressions evaluate interactively (2^3+2 β†’ 10).
  • Basic types βž” numeric (10.5), integer (as.integer(10.5)), complex (1+2i), logical (TRUE), character ("Intro To R").
  • Inspect / test / convert βž” class(x) Β· is.integer(x) Β· as.character(x); help(c) for docs.
  • Control flow βž” if(expr){...}, for(i in 1:n){...}, while(cond){...}; break exits, next skips to the next iteration.

πŸ”€ Variations

  • for / while βž” for(i in 1:3) print(i^2) β†’ 1,4,9; a while(i<=6) loop with i = i+1 prints squares.
  • break vs next βž” in for(i in 1:5), if(i==3) break prints 1,2; if(i==3) next prints 1,2,4,5.
  • Two ways to step a loop βž” filter inside (for(i in 1:15) if (i %% 2 == 1) cat(i,"\n")) or generate the right sequence (for(i in seq(1,15,2))) β€” seq(from, to, by) beats a modulo test when the pattern is regular. %% is the remainder operator, %/% integer division.
  • Printing inside loops and functions βž” R suppresses auto-printing there, so use cat("value:", i, "\n"); \n forces the newline (print() also works but formats less freely).

Workspace and help

  • Session objects βž” ls() lists them Β· rm(x, y) removes named ones Β· rm(list=ls()) clears everything (the standard clean-slate line at the top of a script).
  • Help βž” help("ls") (or ?ls) opens the doc β€” the examples at the bottom are the fastest way in; apropos("med") keyword-searches command names when you can’t recall one.
  • Script files βž” put commands in studio1.R and run with source("studio1.R") βž” reproducibility: the script, not the console history, is the record of an analysis. Comment with #; whitespace is ignored, so use it.

User-defined functions

myfactorial <- function(n)
{
  if (n < 0 || floor(n) != n)          # error checking FIRST
  {
    stop("n must be non-negative integer")
  }
  if (n == 0) { return(1) }            # base case
  else        { return(n * myfactorial(n-1)) }   # recursive case
}
myfactorial(4)   # 24
  • Definition βž” name <- function(args) { ... }; return(value) hands a value back.
  • Not usable until executed βž” defining a function in a script does nothing until you source it; re-running the definition overwrites the old one, so no need to delete first.
  • Integer test idiom βž” floor(n) != n detects a non-integer (); stop() aborts with a message.
  • || vs | βž” || is the scalar OR for if conditions (short-circuits on the first value); | is the element-wise OR for vectors. ! negates: !is.numeric(x) reads β€œnot numeric”.

Returning several values with a list

findminmax <- function(x)
{
  if (!is.numeric(x) || !is.vector(x)) { stop("Input must be a numeric vector") }
  retval = list()                        # the container
  retval$min = Inf; retval$max = -Inf    # sentinels: any real value beats them
  for (i in 1:length(x))
  {
    if (x[i] < retval$min) { retval$min = x[i] }
    if (x[i] > retval$max) { retval$max = x[i] }
  }
  retval$rng = retval$max - retval$min
  return(retval)
}
findminmax(c(4,3,10,33,-2,8))    # $min -2, $max 33, $rng 35
  • list() is R’s multi-value return βž” add fields with $; lists nest freely (retval$c$g) and hold mixed types (numbers, strings, other lists).
  • Sentinel initialisation βž” starting at Inf / -Inf guarantees the first comparison replaces it β€” safer than seeding with x[1].

✍️ Practice

⚠️ Common Mistakes

  • πŸ’‘ Use <-, and numbers default to numeric βž” 10 is "numeric", not integer; wrap with as.integer() when you truly need an integer.
  • πŸ’‘ break β‰  next βž” break exits the loop; next only skips the rest of the current pass.
  • πŸ’‘ Loops and functions don’t auto-print βž” a bare i inside a loop shows nothing; use cat() or print().
  • πŸ’‘ A function must be executed before it exists βž” editing the definition in a script changes nothing until you source it again; a stale definition in memory is a classic phantom bug.
  • πŸ’‘ Recursion needs a reachable base case βž” myfactorial(-1) without the stop() guard recurses forever; validate the argument before the recursive call.