[![](https://img.shields.io/badge/download%20html-blue)](../rendered-html/vectors-matrices.html)
[![](https://img.shields.io/badge/download%20Rmd-blue)](vectors-matrices.Rmd)

```{r setup, include=FALSE}
# Set global options for all code chunks in this document
knitr::opts_chunk$set(echo = TRUE)  # Display code alongside its output
```

## Introduction

In R, vectors and matrices are fundamental data structures that allow us to work with collections of data. They are especially important in bioinformatics and RNA-seq analysis, where we often need to handle large sets of gene expression values or sample measurements.

Key concepts we'll cover:
- Vectors: One-dimensional arrays of values
- Matrices: Two-dimensional arrays of values
- Operations and functions for both data types
- Real-world applications in RNA-seq analysis

## Vectors

A vector is a one-dimensional array that can hold elements of the same type (numeric, character, or logical). Think of it as a single row or column of data.

### Creating Vectors

There are several ways to create vectors in R. Here are common methods with bioinformatics examples:

```{r creating-vectors}
# Create vectors using c() (combine) function for different data types
gene_expression <- c(156.7, 238.9, 184.3, 145.6)  # Numeric vector: Expression values in TPM
gene_names <- c("BRCA1", "TP53", "EGFR", "KRAS")  # Character vector: Gene symbols
is_significant <- c(TRUE, FALSE, TRUE, TRUE)       # Logical vector: Significance flags (p < 0.05)

# Create a sequence using the : operator
# Useful for sample numbers or time points
sample_numbers <- 1:10                # Creates sequence from 1 to 10 (e.g., patient IDs)

# Create more complex sequences using seq()
# Perfect for time series experiments
time_points <- seq(0, 48, by = 6)     # Creates sequence 0,6,12,...,48 (hours post-treatment)

# Display the created vectors
print("Gene Expression Values:")      # TPM values for each gene
print(gene_expression)
print("Gene Names:")                  # Corresponding gene symbols
print(gene_names)
```

### Vector Operations

Vectors in R support element-wise operations, making them perfect for data transformations:

```{r vector-operations}
# Example: RNA-seq data normalization
raw_counts <- c(1200, 1500, 800, 2000)     # Raw read counts from sequencing
scaling_factor <- 0.5                       # Library size normalization factor
normalized_counts <- raw_counts * scaling_factor  # Scale counts by library size

# Compare control vs treated samples
control_expression <- c(100, 150, 80, 200)      # Expression in control condition
treated_expression <- c(150, 180, 90, 250)      # Expression after treatment
expression_difference <- treated_expression - control_expression  # Absolute change

# Calculate fold change (treated/control)
# A common metric in differential expression analysis
fold_change <- treated_expression / control_expression  # Relative change

# Display results of calculations
print("Normalized counts:")                # Library-size normalized values
print(normalized_counts)
print("Expression difference:")            # Absolute expression changes
print(expression_difference)
print("Fold change:")                      # Relative expression changes
print(fold_change)
```

### Vector Functions

R provides many useful functions for working with vectors. These are essential for data analysis:

```{r vector-functions}
# Basic vector operations
print("Length of gene_names:")            # Number of genes in our dataset
length(gene_names)                        # Count elements in vector

# Calculate common statistical measures
print("Summary statistics for raw_counts:")
mean(raw_counts)                          # Average expression level
median(raw_counts)                        # Middle expression value (robust to outliers)
max(raw_counts)                          # Highest expression value
min(raw_counts)                          # Lowest expression value
sum(raw_counts)                          # Total counts (library size)

# Sort values (useful for ranking genes)
sorted_counts <- sort(raw_counts)         # Sort by expression (ascending)
sorted_counts_desc <- sort(raw_counts, decreasing = TRUE)  # Find highest expressed genes

print("Sorted counts (ascending):")       # Show expression ranking
print(sorted_counts)
print("Sorted counts (descending):")      # Show highest to lowest
print(sorted_counts_desc)

# Find unique elements (useful for finding unique genes/features)
unique_genes <- unique(gene_names)        # Remove duplicate gene names
print("Unique genes:")                    # Show deduplicated list
print(unique_genes)
```

### Accessing Vector Elements

Elements in vectors can be accessed using indices or logical conditions. This is crucial for filtering data:

```{r vector-access}
# Access elements by position (1-based indexing in R)
first_gene <- gene_names[1]               # Get first gene in list
selected_genes <- gene_names[c(1, 3)]     # Get specific genes of interest

# Access elements by condition (logical filtering)
high_expression <- raw_counts > 1000      # Find highly expressed genes
high_expressed_genes <- gene_names[high_expression]  # Get names of high expressors

# Use which() to get indices of TRUE values
# Useful for finding significant results
significant_indices <- which(is_significant)  # Find significant results
significant_genes <- gene_names[significant_indices]  # Get significant gene names

# Display results of different access methods
print("First gene:")                      # Single gene access
print(first_gene)
print("Selected genes:")                  # Multiple gene access
print(selected_genes)
print("Highly expressed genes:")          # Filtered gene list
print(high_expressed_genes)
```

## Matrices

Matrices are two-dimensional arrays that also hold elements of the same type. They are particularly useful for representing expression data where:
- Rows typically represent genes or features
- Columns typically represent samples or conditions

### Creating Matrices

```{r creating-matrices}
# Create a matrix from vector data
# This could represent an expression matrix with:
# - 3 genes (rows)
# - 4 samples (columns)
expression_matrix <- matrix(
  c(100, 200, 150, 300,    # Expression values for Gene1
    120, 180, 160, 280,    # Expression values for Gene2
    90, 220, 170, 320),    # Expression values for Gene3
  nrow = 3,                # Number of genes
  ncol = 4,                # Number of samples
  byrow = TRUE            # Fill matrix by rows (each row = one gene)
)

# Add descriptive names to rows (genes) and columns (samples)
rownames(expression_matrix) <- c("Gene1", "Gene2", "Gene3")  # Gene IDs
colnames(expression_matrix) <- c("Sample1", "Sample2", "Sample3", "Sample4")  # Sample IDs

# Display the created matrix
print("Expression Matrix:")               # Show expression data table
print(expression_matrix)
```

### Matrix Operations

```{r matrix-operations}
# Demonstrate common matrix transformations used in bioinformatics
transposed_matrix <- t(expression_matrix)  # Transpose (useful for certain analyses)

# Matrix multiplication (used in many statistical methods)
# For example, calculating correlation between samples
correlation_matrix <- t(expression_matrix) %*% expression_matrix  # Sample correlations

# Element-wise operations (common in data preprocessing)
scaled_matrix <- expression_matrix * 2     # Scale up all values
log_matrix <- log2(expression_matrix)      # Log2 transform (standard in RNA-seq)

# Display results of matrix operations
print("Transposed Matrix:")               # Genes as columns, samples as rows
print(transposed_matrix)
print("\nCorrelation Matrix:")            # Sample-to-sample correlations
print(correlation_matrix)
print("\nLog2 Transformed Matrix:")       # Log2-transformed expression values
print(log_matrix)
```

### Accessing Matrix Elements

```{r matrix-access}
# Access individual elements and subsets of the matrix
value <- expression_matrix[1, 2]           # Expression of Gene1 in Sample2
gene1_expression <- expression_matrix[1, ]  # All samples for Gene1
sample1_values <- expression_matrix[, 1]    # All genes in Sample1
subset_matrix <- expression_matrix[1:2, c(1,3)]  # Expression for 2 genes in 2 samples

# Display different types of matrix access
print("Value at position [1,2]:")          # Single expression value
print(value)
print("\nExpression values for Gene1:")    # Expression profile of one gene
print(gene1_expression)
print("\nValues for Sample1:")             # Expression profile of one sample
print(sample1_values)
print("\nSubset Matrix:")                  # Selected genes and samples
print(subset_matrix)
```

## Practice Exercises

1. Create a vector of p-values and find which genes are significant (p < 0.05)
2. Calculate the log2 fold change instead of regular fold change
3. Find genes that are both:
   - Significantly changed (fold change > 1.5)
   - Highly expressed (mean expression > 1000)

## Tips for Working with Vectors and Matrices

1. **Always check dimensions**
   - Use `dim()` for matrices
   - Use `length()` for vectors
   - Ensure your data is structured as expected

2. **Handle missing values**
   - Use `is.na()` to find missing values
   - Consider how to handle them (remove, impute, etc.)

3. **Choose appropriate transformations**
   - Log transformation for skewed data
   - Scaling/normalization when comparing samples
   - Consider the biological meaning of your data

4. **Document your analysis**
   - Add clear comments
   - Use meaningful variable names
   - Keep track of transformations applied

## Next Steps

After mastering vectors and matrices, you can move on to:
- Working with data frames
- Statistical analysis and hypothesis testing
- Advanced visualization techniques
- Machine learning applications in R 
