Lecture 5: Core Syntax, Data Types & Computational Logic
2026-10-07
Modern cancer transcriptomics produces massive, high-dimensional datasets:
🧬 The REAL Scale of Transcriptomics
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!
🧬 The REAL Scale of Transcriptomics
produces massive, high-dimensional datasets:
Source: spatialdata.scverse.org
⚠️ Why Excel isn’t the tool?
SEPT2 \(\rightarrow\) 2-SepMARCH1 \(\rightarrow\) 1-Mar⚠️ Why Excel isn’t the tool?
⚠️ Why Excel isn’t the tool?
💡 Instead… We use R! (and Bioconductor)
💡 Instead… We use R! (and Bioconductor)
💡 Instead… We use R! (and Bioconductor)
ggplot2 and specialized spatial graphics engines.Source: benwhalley.github.io
🛠️ How to Install R?
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.
🛠️ How to Install R?
R is free and open source: install R (the engine that runs your code), then RStudio (the editor you work in).
sudo apt install r-base r-base-devCheck what you actually got:
.deb for Debian/Ubuntu, .rpm for Fedora🧩 Engine vs. Editor
R is the language; RStudio is the cockpit. Keep Rscript for cluster pipelines.
🛠️ How to Install R?
🧭 Never lose your work
An unsaved script is lost forever — use File → Save (Ctrl/Cmd + S) after every edit.
🛠️ How to Install R?
Ctrl/Cmd + Shift + X) → R Extension by REditorSupport: REPL, highlighting, debugger, plot pane.
code --install-extension REditorSupport.rR: Select R interpreter → choose your RCtrl + Enter runs the line — just like RStudio’s console.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.
🛠️ How to Install R?
Google Colab runs R on Google’s servers in your browser — nothing to install, and the notebook lives in your Drive.
Runtime → Change runtime type → RCtrl + Enter (Cmd + Enter on Mac)⚠️ 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.
<-)In R, code executes sequentially from top to bottom.
Note
print() wraps strings in quotes "" and outputs a vector index [1].
In R, bare expressions evaluate and print their result automatically.
Tip
You do not need to wrap math inside print().
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!
") or parenthesis ()), R does not crash.+ 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.
Your Turn!
"Preprocessing..."4992 + 1200 using print().Solution:
In 10x Visium, each standard capture area contains exactly 4,992 barcoded spots!
<-)<-)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!
_), and periods (.)1gene causes a syntax error!cell count is invalid!Gene_A, gene_A, and gene_a are 3 completely different variables in memory!💡 Why underscores work
R variable names cannot contain math operators like -. Use snake_case instead.
💡 Why names must start with a letter
R requires variable names to begin with an alphabetic letter.
💡 Why casing matters
target_gene and Target_gene refer to two completely different memory locations!
snake_case for ReadabilityIn 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!
Your Turn!
4992 total capture spots. Assign this number to a variable named total_spots.3820 spots are covered by tissue. Assign this to tissue_spots.background_spots.print(background_spots).Solution:
Tip
In spatial analysis, tissue spots capture cellular mRNA, while background spots are filtered out during quality control!
<-)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):
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!
NA (Not Available)NA represents missing data, unmeasured spots, or biological dropouts.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)!
NaN (Not a Number)NaN stands for “Not a Number”.is.nan():Tip
In single-cell normalization, dividing a gene count of 0 by an empty spot’s library size of 0 yields NaN.
Inf & -Inf (Infinity)Inf and -Inf represent values exceeding numerical bounds.🧬 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)\))!
<-)| 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.
Tip
In transcriptomics, \(\log_2\) is standard because a 1-unit increase represents a doubling (2-fold increase) in gene expression!
Which gene is actually expressed at a higher relative rate?
\[\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.
<-)A string stores text data. In R, strings can be created using matching double (") or single (') quotes:
'text' and "text" identically in memory." are strongly preferred across Bioconductor and Tidyverse codebases.Golden Rule
Never mix opening and closing types (e.g., "text' will throw a syntax error)!
What happens when your text itself contains quotation marks or apostrophes?
'Expression: "High"'"Patient's sample"Why this matters?
If you don’t use the opposite quote type, R gets confused about where the string ends!
To print clean sentences and combine text smoothly with variables, R provides cat() (short for con-cat-enate):
cat()?
print() wraps text in quotes and adds vector indices ([1]).cat() combines multiple pieces into readable terminal sentences!"\n" Rule:
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!
\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!
"data\visium\counts.csv"\ is the escape character, R tried to parse \v and \c as escape codes!\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!
<-)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 |
&)Returns TRUE only if both conditions are TRUE.
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.
|)Returns TRUE if at least one condition is TRUE.
FALSE only if both sides are FALSE.| Left | Right | Left | Right |
|---|---|---|
TRUE |
TRUE |
TRUE |
TRUE |
FALSE |
TRUE |
FALSE |
TRUE |
TRUE |
FALSE |
FALSE |
FALSE |
!)Inverts any truth value (TRUE \(\rightarrow\) FALSE, FALSE \(\rightarrow\) TRUE).
| Input | !Input |
|---|---|
TRUE |
FALSE |
FALSE |
TRUE |
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:
on_tissue is TRUEgene_count is at least 500 AND at most 2500mito_pct is less than 20.0on_tissue == TRUE (or simply on_tissue) \(\rightarrow\) TRUE(gene_count >= 500) & (gene_count <= 2500) \(\rightarrow\) TRUEmito_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).
<-)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?
else if to test additional checks in order.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:
gene) holds the current value.nextnext skips the rest of the current iteration.break!break terminates and exits the loop immediately.while TRUE?Repeats code block as long as a condition stays TRUE:
Avoid Infinite Loops
FALSE, the loop runs infinitely!You are given read counts from 5 spatial spots:
Write a for loop that iterates over spot_counts:
50, skip it using next.>= 1000:
>= 1000, print: "Count [x]: High"< 1000, print: "Count [x]: Standard"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.
<-)📓 Interactive Notebook
Launch the companion notebook: lecture-05_r_fundamentals_practice.ipynb
In the next session, we will learn how to load 10x Genomics Visium count matrices and spot coordinates into R!
read.csv() and fast fread().“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!”
Fighting Cancer with Transcriptomics - Lecture 05