Back to Course
Advanced Structures

Advanced Structures — Data Frames and Lists

Real-world datasets rarely contain just one data type. Data frames and lists are R's answer to storing mixed, structured, and hierarchical data — and they're what you'll use in almost every real analysis.

1. Data Frames — R's Spreadsheet

A data frame is a table where each column can hold a different data type (numeric, character, logical), but every column must have the same length.

df <- data.frame(
  name = c("Alice", "Bob", "Carol"),
  age = c(25, 32, 29),
  active = c(TRUE, FALSE, TRUE),
  stringsAsFactors = FALSE
)
print(df)
str(df)     # structure overview
nrow(df)    # 3
ncol(df)    # 3
names(df)   # column names

2. Subsetting Data Frames

SyntaxMeaning
df$ageAccess a column by name (returns a vector)
df[, 2]Access column 2 by position
df[1, ]Access row 1 (all columns)
df[1, "age"]Access row 1, column 'age'
df[df$age > 27, ]Filter rows using a logical condition
df[["name"]]Access column as a vector (like $)
df$age               # 25 32 29
df[df$age > 27, ]    # rows where age > 27
df[, c("name", "age")]  # select specific columns
Pro Tip: df$col and df[["col"]] both return a vector. df[, "col"] (single bracket) can behave differently depending on options — prefer $ or [[ ]] for clarity.

3. Lists — R's Most Flexible Structure

A list can hold elements of completely different types and lengths — even other lists, data frames, or functions. Think of it as a flexible container.

my_list <- list(
  name = "Project Alpha",
  scores = c(88, 92, 79),
  metadata = list(year = 2026, active = TRUE)
)

my_list$name          # "Project Alpha"
my_list[["scores"]]   # 88 92 79
my_list$metadata$year # 2026
length(my_list)       # 3

4. Single Bracket [ ] vs. Double Bracket [[ ]]

This distinction confuses many beginners but is critical:

SyntaxReturnsExample
list[1]A sub-list containing element 1class(my_list[1]) → "list"
list[[1]]The actual element itselfclass(my_list[[1]]) → "character"
my_list[1]     # list of length 1, still wrapped in list()
my_list[[1]]   # "Project Alpha" — the raw value
Production Reality: Use [[ ]] when you want the actual value out. Use [ ] only when you deliberately want to keep the list wrapper (e.g., for iteration).

5. Adding and Removing Elements

df$score <- c(88, 92, 79)     # add new column
df$active <- NULL             # remove a column

my_list$new_field <- "added"  # add to list
my_list$name <- NULL          # remove from list

6. Production-Ready Checklist

  • ✅ Use data frames for tabular, rectangular data — rows and columns, mixed types.
  • ✅ Use lists for irregular or hierarchical data — nested, unequal-length elements.
  • ✅ Master $ vs [ ] vs [[ ]] — the most common source of subsetting confusion.
  • ✅ Use str() liberally — the fastest way to understand any object's structure.
Pro Tip: Almost every real-world dataset you import in R will land as a data frame (or its modern cousin, the tibble). Getting comfortable with subsetting here pays off across the entire course.

Ready to master R Programming?

Build real-world data analysis and visualization projects with hands-on training, mentor-led sessions, and placement support.

Explore Course