🧬 R Programming Fundamentals

Lecture 5: Core Syntax, Data Types & Computational Logic

Fighting Cancer with Transcriptomics 2026

2026-10-07

🗺️ Where We Are in the Course

Why R?

🧬 The REAL Scale of Transcriptomics

Modern cancer transcriptomics produces massive, high-dimensional datasets:

  • Bulk RNA-Seq:
    • ~20,000 human genes quantified across patient cohorts.
    • Millions of sequencing reads per sample.

Example: Bulk RNA-Seq Count Matrix

How raw transcriptomic data looks in a computational matrix

Gene ID Tumor_P1 Tumor_P2 Normal_P1 Normal_P2
TP53 12,450 14,210 8,920 9,150
BRCA1 3,420 4,890 1,230 1,410
EGFR 45,820 38,100 5,420 6,100
GAPDH 102,400 98,350 95,800 99,200
(… 19,996 more) … … … …

Note

Notice how GAPDH (housekeeping) is steady across all samples, while oncogenes like EGFR are specifically amplified in Tumor samples!

Modern cancer transcriptomics

produces massive, high-dimensional datasets:

  • Single-Cell & Spatial Transcriptomics:
    • Measures expression across thousands of individual cells or tissue spots.
    • Count matrices easily exceed MILLIONS of data points per tumor biopsy.

⚠️ Why Excel isn’t the tool?

1. Gene Date Corruption

  • Silent auto-conversion:
    • SEPT2 \(\rightarrow\) 2-Sep
    • MARCH1 \(\rightarrow\) 1-Mar
  • >30% of published genomics papers contained Excel date errors in supplementary files.
  • Once saved, original gene identities are PERMANANTLY lost.

2. Hard Capacity Limits

  • 1,048,576 rows hard ceiling per sheet.
  • Spatial & single-cell datasets profile 20,000+ genes \(\times\) tens of thousands of spots/cells.
  • Large matrices easily crash or silently truncate data.

3. Lack of Reproducibility

  • No audit trail: Point-and-click edits leave no record.
  • Impossible to trace cell filtering, modifications, or outlier removal.
  • Code is a protocol: R scripts are version-controlled, automated, and 100% reproducible.

💡 Instead… We use R! (and Bioconductor)

1. The Bioconductor Ecosystem

  • Purpose-built for genomics: 2,000+ specialized, peer-reviewed packages.
  • Cancer & spatial standards: Standardized data structures for bulk, single-cell, and spatial transcriptomics.

2. 100% Reproducible Research

  • Self-documenting workflows:
    • Every normalization, filter, and cutoff is explicitly preserved in code.
  • Full audit trail:
    • Anyone can re-run the script from raw data to reproduce the exact same results.

3. Publication-Grade Visualizations

  • High-impact science communication:
    • Powered by ggplot2 and specialized spatial graphics engines.
  • Pixel-perfect control:
    • Volcano plots, Heatmaps, and Spatial tissue overlays built directly for publication.

🛠️ How to Install R?

3 Ways to Get R Running

  • 1. Local install — R from CRAN + RStudio Desktop on your own machine
  • 2. Google Colab — R on Google’s servers, nothing to install: colab.to/r
  • 3. Micromamba — a reproducible environment.yml toolbox (our course standard)

🎯 Pick one for today

Any of these allows you to run the exact same R. Start with the easiest, add the others when you need them.

The Local Route: CRAN + RStudio

R is free and open source: install R (the engine that runs your code), then RStudio (the editor you work in).

Install R

Check what you actually got:

Install RStudio

🧩 Engine vs. Editor

R is the language; RStudio is the cockpit. Keep Rscript for cluster pipelines.

RStudio IDE

🧭 Never lose your work

An unsaved script is lost forever — use File → Save (Ctrl/Cmd + S) after every edit.

VS Code Works Too!

Install on Ubuntu

# Easiest — snap:
sudo snap install code --classic

# Or grab the .deb from code.visualstudio.com, then:
sudo apt install ./code_*.deb
  • Extensions (Ctrl/Cmd + Shift + X) → R Extension by REditorSupport: REPL, highlighting, debugger, plot pane.
    • Or from the terminal: code --install-extension REditorSupport.r

Point It at Your R

  • R: Select R interpreter → choose your R
  • Type in the R Terminal, Ctrl + Enter runs the line — just like RStudio’s console.
  • Shell: code analysis.R · headless: Rscript analysis.R

🤝 Either Editor Is Fine

RStudio is all-in-one; VS Code wins when you work across languages. Both run the exact same R.

R in Google Colab - Skip Installation Entirely!

Google Colab runs R on Google’s servers in your browser — nothing to install, and the notebook lives in your Drive.

  • Open an R notebook at colab.to/r, or set Runtime → Change runtime type → R
  • Type code in a code cell, then press Ctrl + Enter (Cmd + Enter on Mac)
  • Missing a package? Install it once, then load it:
# 1. Install (once per session)
install.packages("ggplot2")

# 2. Load it so your code can use it
library(ggplot2)

⚠️ Colab Is Not Persistent

Colab runs on a temporary server — when the session disconnects or goes idle it is wiped clean, and every installed package and uploaded file disappears. Save anything you want to keep to your Drive before you close the tab.

📋 1. Syntax, Comments & Output

  • 1. Syntax, Comments & Output
    1. Variables & The Assignment Operator (<-)
    1. Core Data Types & Values
    1. R Math Functions & Arithmetic Operators
    1. Strings & Escape Characters
    1. R Operators
    1. Control Flow (If…Else, Loops)
    1. Practice Exercises

Hello World! 🌏

In R, code executes sequentially from top to bottom.

Note

print() wraps strings in quotes "" and outputs a vector index [1].

Let’s do some math! 🔢

In R, bare expressions evaluate and print their result automatically.

Tip

You do not need to wrap math inside print().

Displaying Values with print() 🖨️

Use print() to display text messages and numeric values to the console:

Note

Notice that print() outputs [1] before the value. This indicates that the output is a vector whose first element starts at index 1!

Uh oh! ⁉️ Mistakes Happen… A LOT!

  • If you miss a closing quote (") or parenthesis ()), R does not crash.
  • It waits on a new line showing a + prompt!

💡 How to Rescue Your Console

Press Escape or Ctrl + C to cancel and recover your prompt >!

Golden Rule: Quotes "" and parentheses () must always match in pairs.

✍️ Exercise 1.1: Spot Count Check

Your Turn!

  1. Write a comment with your name and today’s date.
  2. Print the message: "Preprocessing..."
  3. Calculate the total spots on a slide by adding 4992 + 1200 using print().

✅ Exercise 1.1: Spot Count Check

Solution:

In 10x Visium, each standard capture area contains exactly 4,992 barcoded spots!

📋 2. Variables & The Assignment Operator (<-)

    1. Syntax, Comments & Output
  • 2. Variables & The Assignment Operator (<-)
    1. Core Data Types & Values
    1. R Math Functions & Arithmetic Operators
    1. Strings & Escape Characters
    1. R Operators
    1. Control Flow (If…Else, Loops)
    1. Practice Exercises

Named Storage Containers in Memory

A variable is a named storage container in your computer’s memory.

💡 Why not =?

While = works, R and Bioconductor standards strictly recommend <- for variable assignment, reserving = for passing arguments inside functions!

Rules for Variable Names

✅ DOs

  • Must start with a letter:
  • Can contain:
    • Letters, numbers, underscores (_), and periods (.)
  • Clean, descriptive names make code readable for peers and reviewers!

🛑 DON’Ts

  • Cannot start with a number:
    • 1gene causes a syntax error!
  • Cannot contain spaces:
    • cell count is invalid!
  • R is strictly case-sensitive:
    • Gene_A, gene_A, and gene_a are 3 completely different variables in memory!

🔍 Spot the Error!

✅ Solution: Hyphens in names

💡 Why underscores work

R variable names cannot contain math operators like -. Use snake_case instead.

🔍 Spot the Error!

✅ Solution: Leading digits

💡 Why names must start with a letter

R requires variable names to begin with an alphabetic letter.

🔍 Spot the Error!

✅ Solution: Variables are Case-sensitive

💡 Why casing matters

target_gene and Target_gene refer to two completely different memory locations!

Use snake_case for Readability

In standard bioinformatics and tidy R workflows, use snake_case (all lowercase words separated by underscores):

Tip

Using lowercase with underscores avoids accidental typos, prevents case-sensitivity errors, and keeps pipelines clean!

✍️ Exercise 1.2: Calculating Background Spots

Your Turn!

  1. A 10x Visium slide has 4992 total capture spots. Assign this number to a variable named total_spots.
  2. Microscope imaging reveals that 3820 spots are covered by tissue. Assign this to tissue_spots.
  3. Calculate the number of background (empty) spots and store it in background_spots.
  4. Print the result using print(background_spots).

✅ Exercise 1.2: Calculating Background Spots

Solution:

Tip

In spatial analysis, tissue spots capture cellular mRNA, while background spots are filtered out during quality control!

📋 3. Core Data Types & Values

    1. Syntax, Comments & Output
    1. Variables & The Assignment Operator (<-)
  • 3. Core Data Types & Values
    1. R Math Functions & Arithmetic Operators
    1. Strings & Escape Characters
    1. R Operators
    1. Control Flow (If…Else, Loops)
    1. Practice Exercises

Every piece of data in R belongs to a specific atomic type:

Type What It Stores Real Genomics Example
numeric Decimals / Floats (default in R) log2_fc <- 2.45
integer Discrete counts / whole numbers (L) raw_reads <- 12450L
character Text strings ("") gene_name <- "TP53"
logical Boolean (TRUE/FALSE, no quotes!) is_de_gene <- TRUE

Note

In R, numbers default to numeric (double). To explicitly store an integer (e.g., spot index or raw read count), append an L like 4992L.

Inspect any variable with typeof() or class():

Combining different types forces everything to the most flexible type (character):

🧬 Bioinformatics Pitfall: Type Coercion

Vectors can hold only one type! If you mix types, R silently coerces everything to the most flexible type (character):

💥 Why did sum() fail?

Because "NA" is text, R converted all numbers into character strings ("120", "450", "310"). R cannot perform math on strings!

⚠️ Special Values: NA (Not Available)

  • NA represents missing data, unmeasured spots, or biological dropouts.
  • Extremely common in single-cell & spatial transcriptomics datasets.
  • Test for missing values using is.na() (never == NA):

💡 Gotcha: Never use == NA

x == NA returns NA because comparing anything to an unknown is unknown. Always use is.na(x)!

⚠️ Special Values: NaN (Not a Number)

  • NaN stands for “Not a Number”.
  • Occurs when a mathematical operation is undefined or impossible (e.g., \(0 / 0\)).
  • Test for undefined values using is.nan():

Tip

In single-cell normalization, dividing a gene count of 0 by an empty spot’s library size of 0 yields NaN.

⚠️ Special Values: Inf & -Inf (Infinity)

  • Inf and -Inf represent values exceeding numerical bounds.
  • Arises when dividing non-zero numbers by zero, or taking the logarithm of zero (\(\log(0)\)).

🧬 Transcriptomic Connection

Gene count matrices contain many zeros. Taking \(\log_2(0) = -\infty\) crashes statistical pipelines — which is why we add a pseudo-count (\(\log_2(\text{count} + 1)\))!

📋 4. R Math Functions & Arithmetic Operators

    1. Syntax, Comments & Output
    1. Variables & The Assignment Operator (<-)
    1. Core Data Types & Values
  • 4. R Math Functions & Arithmetic Operators
    1. Strings & Escape Characters
    1. R Operators
    1. Control Flow (If…Else, Loops)
    1. Practice Exercises

Standard Math Operators in Genomics

Operator Action Real Genomics Example
+ Addition tot_reads <- 12000 + 3500
- Subtraction bg_spots <- 4992 - 3820
* Multiplication mito_pct <- 0.074 * 100
/ Division depth_scale <- 45 / 15000
^ Exponentiation fc <- 2^3 (8-fold change)
%% Modulo (remainder) batch_rem <- 10 %% 3 (1)
%/% Floor division cohort_grp <- 10 %/% 3 (3)

Note

In R, %% returns the remainder (e.g. testing for even/odd samples), while %/% performs floor division, discarding the fractional part.

  1. Square root:
  1. Rounding numbers:
  1. Logarithms (base 2 for fold change):

Tip

In transcriptomics, \(\log_2\) is standard because a 1-unit increase represents a doubling (2-fold increase) in gene expression!

The Problem: Sequencing Depth Differences

# Spot A (high sequencing depth):
spot_a_total_reads <- 50 * 10^6
spot_a_gene_reads  <- 450

# Spot B (lower sequencing depth):
spot_b_total_reads <- 10 * 10^6
spot_b_gene_reads  <- 200
  • Spot A has 50M total reads
  • Spot B has only 10M total reads.

Which gene is actually expressed at a higher relative rate?

The Solution: Counts Per Million (CPM)

\[\text{CPM} = \left( \frac{\text{Gene Read Count}}{\text{Total Library Size}} \right) \times 10^6\]

The Normalization Takeaway

Raw counts deceive!

Although Spot A has more reads (450 vs 200), Spot B actually expresses the gene at 2.2× higher rate once normalized for sequencing depth.

📋 5. Strings & Escape Characters

    1. Syntax, Comments & Output
    1. Variables & The Assignment Operator (<-)
    1. Core Data Types & Values
    1. R Math Functions & Arithmetic Operators
  • 5. Strings & Escape Characters
    1. R Operators
    1. Control Flow (If…Else, Loops)
    1. Practice Exercises

Single vs. Double Quotes

A string stores text data. In R, strings can be created using matching double (") or single (') quotes:

  • Both Are Valid:
    • R treats 'text' and "text" identically in memory.
  • Bioinformatics Standard:
    • Double quotes " are strongly preferred across Bioconductor and Tidyverse codebases.

Golden Rule

Never mix opening and closing types (e.g., "text' will throw a syntax error)!

Quotes Inside Quotes

What happens when your text itself contains quotation marks or apostrophes?

  • Enclose with the Opposite Type:
    • Put double quotes inside single quotes: 'Expression: "High"'
    • Put single quotes (apostrophes) inside double quotes: "Patient's sample"

Why this matters?

If you don’t use the opposite quote type, R gets confused about where the string ends!

Concatenations! 😺

To print clean sentences and combine text smoothly with variables, R provides cat() (short for con-cat-enate):

  • Why use cat()?
    • print() wraps text in quotes and adds vector indices ([1]).
    • cat() combines multiple pieces into readable terminal sentences!
  • The Trailing "\n" Rule:
    • Unlike print(), cat() does not add a newline automatically. Always end with "\n" to advance to the next line.

Note

Notice that "\n" at the end? That is an escape character! Let’s explore what backslashes do next!

Escape Characters (\n, \t, \")

The backslash \ is a special signal in R that modifies the character following it:

Escape Code Meaning What It Does
\n New Line Jumps down to a fresh line
\t Tab Space Inserts a clean column indent
\" Double Quote Puts literal " inside "..."

\ is Special in R!

The backslash tells R: “Don’t treat the next character literally; it is an escape command!”

Tip

Because cat() interprets escape sequences, \" renders as real quotes on screen!

🔍 Trivia

  • A researcher on Windows copies a path from File Explorer: "data\visium\counts.csv"

🔍 The Windows Path Trap — Solution

  • Because \ is the escape character, R tried to parse \v and \c as escape codes!
  • Since \c is not a valid escape sequence (like \n or \t), R crashed.

🌐 The Universal Rule

ALWAYS use forward slashes / in R paths across Windows, macOS, and Linux!

📋 6. R Operators

    1. Syntax, Comments & Output
    1. Variables & The Assignment Operator (<-)
    1. Core Data Types & Values
    1. R Math Functions & Arithmetic Operators
    1. Strings & Escape Characters
  • 6. R Operators
    1. Control Flow (If…Else, Loops)
    1. Practice Exercises

Comparison Operators

Comparison operators test relationships between values. The result is always a logical (TRUE or FALSE).

Operator Meaning Example
== Exactly equal to x == 10
!= Not equal to x != 10
> Greater than x > 5
< Less than x < 5
>= Greater than or equal to x >= 10
<= Less than or equal to x <= 10

Logical AND (&)

Returns TRUE only if both conditions are TRUE.

  • Evaluates left and right conditions.
  • If either side is FALSE, the entire result is FALSE.
Left Right Left & Right
TRUE TRUE TRUE
TRUE FALSE FALSE
FALSE TRUE FALSE
FALSE FALSE FALSE

Precedence Tip

Use parentheses (...) around each comparison to keep compound logic clear.

Logical OR (|)

Returns TRUE if at least one condition is TRUE.

  • Evaluates left and right conditions.
  • Returns FALSE only if both sides are FALSE.
Left Right Left | Right
TRUE TRUE TRUE
TRUE FALSE TRUE
FALSE TRUE TRUE
FALSE FALSE FALSE

Logical NOT (!)

Inverts any truth value (TRUE \(\rightarrow\) FALSE, FALSE \(\rightarrow\) TRUE).

  • Reverses a logical condition.
  • Useful to negate flags or keep unflagged samples.
Input !Input
TRUE FALSE
FALSE TRUE

🔍 Practice: Spot Quality Filter

A spatial spot has been sequenced with these metrics:

Write a compound logical expression for keep_spot. It should evaluate to TRUE only if all 3 conditions pass:

  1. on_tissue is TRUE
  2. gene_count is at least 500 AND at most 2500
  3. mito_pct is less than 20.0

✅ Solution — Spot Quality Filter

  • Condition 1: on_tissue == TRUE (or simply on_tissue) \(\rightarrow\) TRUE
  • Condition 2: (gene_count >= 500) & (gene_count <= 2500) \(\rightarrow\) TRUE
  • Condition 3: mito_pct < 20.0 \(\rightarrow\) FALSE (22.4 < 20 is false)

Overall: TRUE & TRUE & FALSE \(\rightarrow\) FALSE (spot is filtered out).

Chaining Range Checks

In R, you cannot write 500 <= gene_count <= 2500. You must write two separate comparisons joined by &: (gene_count >= 500) & (gene_count <= 2500).

📋 7. Control Flow (If…Else, Loops)

    1. Syntax, Comments & Output
    1. Variables & The Assignment Operator (<-)
    1. Core Data Types & Values
    1. R Math Functions & Arithmetic Operators
    1. Strings & Escape Characters
    1. R Operators
  • 7. Control Flow (If…Else, Loops)
    1. Practice Exercises

Conditional Branching (if...else)

  • if: Runs code block only if condition is TRUE.
  • else: Catch-all fallback if condition is FALSE.

R Syntax Requirement

else must always be on the same line as the closing brace }: } else {

What if you need more conditions?

  • Use else if to test additional checks in order.
  • R runs the first branch that is TRUE, then stops.
  • else catches whatever is left over.

for Loops (Iterating Vectors)

A for loop executes a block of code once for each element in a vector:

  • Iterates sequentially through items in a collection.
  • Inside the loop, the variable (e.g., gene) holds the current value.
  • Commonly used to batch-process gene lists, spots, or file paths.

Skip with next

  • next skips the rest of the current iteration.
  • The loop immediately jumps to the next item in the vector.
  • Useful for filtering out low-quality spots without stopping the entire run.

Take a break!

  • break terminates and exits the loop immediately.
  • No remaining items are processed.
  • Useful for error aborts, corrupted inputs, or stopping early once a condition is met.

while TRUE?

Repeats code block as long as a condition stays TRUE:

  • Condition is checked before each iteration.

Avoid Infinite Loops

  • If the condition never turns FALSE, the loop runs infinitely!
  • Always increment or adjust your counter variable inside the loop body.

🔍 Practice: Filter & Tier Spots

You are given read counts from 5 spatial spots:

Write a for loop that iterates over spot_counts:

  1. If count is below 50, skip it using next.
  2. Otherwise, check if count is >= 1000:
    • If >= 1000, print: "Count [x]: High"
    • If < 1000, print: "Count [x]: Standard"

✅ Solution — Filter and Tier Spots

  • 35 and 20 are < 50, so next skips them before printing.
  • 1250 passes to the if check \(\rightarrow\) "High".
  • 450 and 800 pass to the else branch \(\rightarrow\) "Standard".

Early Exits with next

Using next at the top of a loop is known as a guard clause. It keeps subsequent logic cleaner by discarding invalid inputs early.

📋 8. Practice Exercises

    1. Syntax, Comments & Output
    1. Variables & The Assignment Operator (<-)
    1. Core Data Types & Values
    1. R Math Functions & Arithmetic Operators
    1. Strings & Escape Characters
    1. R Operators
    1. Control Flow (If…Else, Loops)
  • 8. Practice Exercises

🧑‍💻 Hands-on!

📓 Interactive Notebook

Launch the companion notebook: lecture-05_r_fundamentals_practice.ipynb

🚀 What’s Next?

R Data Manipulation - From single values to biological datasets.

In the next session, we will learn how to load 10x Genomics Visium count matrices and spot coordinates into R!

  • Loading External Files: Read spatial matrices with read.csv() and fast fread().
  • Vectors & Factors: Handle thousands of gene readouts at once.
  • Matrices & Data Frames: Work with spatial spot tables and metadata.

Thank You!


“Coding in R is built through muscle memory. Type the code yourself, inspect your variables, and don’t fear errors—they are your best teachers!”