Data Structures & Advanced Concepts
Todayโs Journey
Last week: Variables & Vectors | This week: Complex data structures! ๐๏ธ
Important
Todayโs Challenge: What if we need to store different types together? Or organize data in 2D? Thatโs where lists, matrices, and data frames come in! ๐
Lists: Rโs Swiss Army Knife ๐ง
Lists can hold different types of data, even other lists!
Creating Lists
Why Lists?
# Vectors force one type
mixed_vec <- c(1, "two", TRUE)
mixed_vec
# "1" "two" "TRUE" - all character!
# Lists preserve types
mixed_list <- list(1, "two", TRUE)
mixed_list[[1]] # numeric: 1
mixed_list[[2]] # character: "two"
mixed_list[[3]] # logical: TRUE
# Lists can be nested!
nested <- list(
data = list(x = 1:5, y = 6:10),
meta = list(source = "experiment")
)Matrices: Rows ร Columns of Numbers
Matrices are 2-dimensional arrays of the same type (usually numeric)
By Values
# Create sample matrices
A <- matrix(1:6, nrow=2, ncol=3)
B <- matrix(7:12, nrow=2, ncol=3)
# Element-wise operations
A + B # Add corresponding elements
A * B # Multiply corresponding elements
A / B # Divide corresponding elements
# Matrix multiplication (dimensions must match!)
C <- matrix(1:6, nrow=3, ncol=2)
A %*% C # True matrix multiplication
# Transpose
t(A) # Flip rows and columns
# Other operations
nrow(A) # Number of rows: 2
ncol(A) # Number of columns: 3
dim(A) # Dimensions: 2 3# Create matrix
m <- matrix(1:12, nrow=3, ncol=4)
# Single element
m[1, 2] # Row 1, Column 2: 4
m[3, 4] # Row 3, Column 4: 12
# Entire row or column
m[1, ] # First row: 1 4 7 10
m[, 2] # Second column: 4 5 6
# Multiple rows/columns
m[1:2, ] # Rows 1-2
m[, c(1, 3)] # Columns 1 and 3
# Submatrix
m[1:2, 2:3] # Top-left 2ร2 of middle columns
# With row/column names
colnames(m) <- c("A", "B", "C", "D")
rownames(m) <- c("X", "Y", "Z")
m["X", "B"] # Access by name: 4Data Frames: Excel-like Tables in R
Think of data frames as spreadsheets: - Rows = observations/cases - Columns = variables (can be different types!) - Each column is actually a vector
Mixed Data Types
CSV: Comma-Separated Values
Most common format for sharing data!
# Reading a CSV file
data <- read.csv("mydata.csv")
# Common options
data <- read.csv(
"mydata.csv",
header = TRUE, # First row is column names
sep = ",", # Separator (comma)
stringsAsFactors = FALSE, # Keep strings as text
na.strings = c("NA", "") # What counts as missing?
)
# Quick peek
head(data) # First 6 rows
summary(data) # Statistical summary
# Using tidyverse (better!)
library(readr)
data <- read_csv("mydata.csv") # Smarter defaults!R Comes with Practice Data!
Perfect for learning and testing
Loading Built-in Data
Popular Datasets
mtcars โ 32 cars, 11 variablesiris โ 150 flowers, 5 variablesdiamonds โ 50k+ diamondsairquality โ NYC air qualityChickWeight โ Chick growthToothGrowth โ Tooth growthUSArrests โ Crime statisticsfaithful โ Old Faithful geysermatrix(1:12, nrow=4)?
students <- data.frame(
name = c("Alice", "Bob", "Carol"),
score = c(92, 78, 85),
passed = c(TRUE, TRUE, TRUE)
)
# View it
students
| Structure | Dimensions | Same Type? | Use Case |
|---|---|---|---|
| Vector | 1D | โ Yes | Single variable |
| List | 1D | โ No | Mixed types, complex objects |
| Matrix | 2D | โ Yes | Numeric calculations |
| Data Frame | 2D | โ No | Most data analysis |
Important
Key Insight: Data frames are your go-to for most data science work! Theyโre like spreadsheets with superpowers. ๐ช
plot()Base R Plots Start with Two Columns
Use plot(x, y) to place one numeric variable on the horizontal axis and another on the vertical axis. Add a title, labels, colors, and point styles to make the graph easier to read.
# Create synthetic data for a small class experiment
study_data <- data.frame(
hours_studied = c(1, 2, 3, 4, 5, 6, 7, 8),
exam_score = c(58, 61, 67, 70, 76, 81, 86, 91)
)
# Plot one column against another
plot(study_data$hours_studied, study_data$exam_score,
main = "Study Time and Exam Score",
xlab = "Hours studied",
ylab = "Exam score",
pch = 19,
col = "steelblue")
# Add a fitted trend line to highlight the relationship
abline(lm(exam_score ~ hours_studied, data = study_data),
col = "firebrick", lwd = 2)plot() CallUseful plot() options
type = "p" makes points (the default)type = "l" makes linestype = "b" makes both points and linespch chooses the point shapecol sets the data colormain, xlab, and ylab add readable textR includes the iris data frame: flower measurements for three species. Passing several numeric columns to plot() creates a scatterplot matrix, so we can compare every measurement against every other one at once.
# One color for each iris species
iris_colors <- c("tomato", "goldenrod", "steelblue")[as.numeric(iris$Species)]
# plot.data.frame() creates a scatterplot matrix for the four measurements
plot(iris[1:4],
main = "Relationships Among Iris Measurements",
pch = 19,
col = iris_colors)
legend("topright",
legend = levels(iris$Species),
col = c("tomato", "goldenrod", "steelblue"),
pch = 19,
bty = "n")plot() Code GeneratorWe are going to analyze a dataset called Sunspots which contains monthly sunspot numbers from 1749 to 1983. This dataset is built into R and is a classic example of time series data. Weโll explore its structure, visualize the data, and perform some basic time series analysis.
Important
rm(list = ls()) # clear out the variables from memory to make a clean execution of the code.
# If you want to remove all previous plots and clear the console, run the following two lines.
graphics.off() # clear out all plots from previous work.
cat("\014") # clear the console
if(!require('tidyverse')) {
install.packages('tidyverse')
library('tidyverse')
}
# Load the built-in sunspots dataset (monthly data from 1749 to 1983)
data(sunspots)
# 1. View basic information about the time series
print(start(sunspots)) # Start year/month
print(end(sunspots)) # End year/month
print(frequency(sunspots)) # 12 observations per year (monthly)
# 2. Plot the full time series
plot(sunspots,
main = "Monthly Sunspot Numbers (1749โ1983)",
ylab = "Number of Sunspots",
xlab = "Year",
col = "blue")
# 3. Subset a smaller window to clearly see the 11-year solar cycle
# Let's look at 10 cycles from 1870 to 1970
sunspots_subset <- window(sunspots, start = c(1870, 1), end = c(1970, 12))
plot(sunspots_subset,
main = "Sunspot Cycles (1870โ1970)",
ylab = "Sunspot Count",
xlab = "Year",
col = "darkred")
# 4. Decompose the time series into trend, seasonal, and random components
# Using additive decomposition (frequency = 12)
sunspots_decomp <- decompose(sunspots_subset)
plot(sunspots_decomp)
# 5. Fit a simple Holt-Winters exponential smoothing or autoregressive model
# (Requires forecast package, or use base AR: ar(sunspots_subset))
fit <- ar(sunspots_subset)
print(fit$order) # Shows the optimal autoregressive lag order
# Convert the time series to a data frame for custom ggplot grouping
df <- data.frame(
Year = as.numeric(time(sunspots_subset)),
Month = factor(cycle(sunspots_subset), labels = month.abb),
Count = as.numeric(sunspots_subset)
)
# We will use a new way to visualize the data by month using ggplot2.
# This will allow us to see the sunspot activity for each calendar
# month across the years.
ggplot(df, aes(x = Year, y = Count)) +
geom_line(color = "steelblue") +
facet_wrap(~ Month, ncol = 4) +
labs(title = "Sunspot Activity Split by Calendar Month",
x = "Year",
y = "Sunspot Count") +
theme_light()
# Create 5-year groupings to see macro-cycles
df$YearGroup <- cut(df$Year, breaks = seq(1920, 1975, by = 5), right = FALSE)
ggplot(df, aes(x = YearGroup, y = Count, fill = YearGroup)) +
geom_boxplot(alpha = 0.7, show.legend = FALSE) +
scale_fill_viridis_d(option = "plasma") +
labs(title = "Distribution of Sunspot Counts in 5-Year Blocks",
x = "Year Interval",
y = "Sunspot Count Distribution") +
theme_minimal()Observation: The data reveals a distinct 11-year solar cycle, with peaks in sunspot activity occurring approximately every 11 years. The activity is not evenly distributed across the years, with some periods showing higher activity than others.
Important
Further Analyses: Does your analysis of the sunspot data reveal any other patterns or cycles? How might these patterns be useful for predicting future sunspot activity or understanding solar phenomena?
Tip
Even Further Analyses: Remember that this is just a simplified analysis. More advanced time series techniques (like ARIMA modeling, spectral analysis, or machine learning approaches) could provide deeper insights into the sunspot data and its predictive capabilities.
From Today
โ
Lists โ Flexible containers for mixed data
โ
Matrices โ 2D numeric arrays
โ
Data Frames โ The heart of R data analysis
โ
Reading CSV files
โ
Interactive tools for building data structures
โ
Basic plotting with plot()
โ
Some experience with ggplot2 (more coming soon)
Up Next: Data Manipulation with dplyr
๐ Practice: Create data frames, explore built-in datasets
๐ป Install: install.packages("tidyverse")
๐ฎ Preview: Weโll learn the powerful dplyr verbs for data wrangling!