R — Data Frames
What is a data frame?
A data frame is a table where each column can be a different type, but every column must have the same length:
students <- data.frame(
name = c("Alice", "Bob", "Charlie"),
age = c(20, 22, 19),
grade = c("A", "B", "A"),
passed = c(TRUE, TRUE, TRUE)
)
print(students)
# name age grade passed
# 1 Alice 20 A TRUE
# 2 Bob 22 B TRUE
# 3 Charlie 19 A TRUE
Data frames are R's equivalent of spreadsheets, SQL tables, or Python DataFrames.
Creating data frames
# From vectors
df <- data.frame(
x = 1:5,
y = c("a", "b", "c", "d", "e"),
z = rnorm(5)
)
# From existing data
df <- as.data.frame(matrix(1:12, nrow = 3))
# Empty data frame
df <- data.frame()
Accessing data
students <- data.frame(
name = c("Alice", "Bob", "Charlie"),
age = c(20, 22, 19),
grade = c("A", "B", "A")
)
# By column name
students$name # "Alice" "Bob" "Charlie"
students[["age"]] # 20 22 19
# By position
students[, 1] # first column
students[1, ] # first row
students[1, 2] # row 1, column 2 (20)
# Multiple columns
students[, c("name", "grade")]
# Subset rows by condition
students[students$age > 20, ]
students[students$grade == "A", ]
Adding and removing columns
students <- data.frame(
name = c("Alice", "Bob"),
age = c(20, 22)
)
# Add column
students$gpa <- c(3.8, 3.5)
students["city"] <- c("NYC", "LA")
# Remove column
students$gpa <- NULL
# Add row
students <- rbind(students, data.frame(name = "Charlie", age = 19))
Data frame functions
# Structure
str(students)
# Summary statistics
summary(students)
# Dimensions
dim(students) # rows columns
nrow(students) # number of rows
ncol(students) # number of columns
# Names
names(students) # column names
colnames(students) # same thing
# Head and tail
head(students, 2) # first 2 rows
tail(students, 2) # last 2 rows
The dplyr package
dplyr is the modern way to work with data frames:
library(dplyr)
# Filter rows
students %>% filter(age > 20)
# Select columns
students %>% select(name, grade)
# Mutate — add/modify columns
students %>% mutate(gpa = round(gpa, 1))
# Arrange — sort
students %>% arrange(desc(age))
# Summarize — aggregate
students %>% summarize(
avg_age = mean(age),
count = n()
)
# Group by
students %>%
group_by(grade) %>%
summarize(avg_age = mean(age))
The pipe operator with dplyr
library(dplyr)
# Chain operations
result <- mtcars %>%
filter(cyl == 6) %>%
select(mpg, hp, wt) %>%
arrange(desc(mpg)) %>%
head(5)
print(result)
The pipe %>% passes the result of each step to the next. Code reads like a pipeline of transformations.
Row operations
df <- data.frame(x = c(1, 2, 3), y = c(4, 5, 6))
# Add rows
df <- rbind(df, data.frame(x = 7, y = 8))
# Remove rows
df <- df[-1, ] # remove first row
df <- df[df$x > 1, ] # keep rows where x > 1
# Order rows
df[order(df$x), ]
Column operations
df <- data.frame(a = 1:5, b = 6:10, c = 11:15)
# Rename columns
names(df) <- c("first", "second", "third")
# Select columns
df[, c("first", "third")]
# Reorder columns
df[, c("third", "first", "second")]
# Column arithmetic
df$sum <- df$first + df$second
Handling missing values
df <- data.frame(
x = c(1, 2, NA, 4, 5),
y = c(NA, 2, 3, NA, 5)
)
# Check for NAs
is.na(df) # logical matrix
colSums(is.na(df)) # NAs per column
# Remove rows with any NA
na.omit(df)
df[complete.cases(df), ]
# Replace NAs
df$x[is.na(df$x)] <- 0
df$y[is.na(df$y)] <- mean(df$y, na.rm = TRUE)
# tidyr approach
library(tidyr)
df %>% tidyr::drop_na()
Merging data frames
students <- data.frame(
id = c(1, 2, 3),
name = c("Alice", "Bob", "Charlie")
)
scores <- data.frame(
id = c(1, 2, 3),
score = c(95, 87, 92)
)
# Inner join — only matching rows
merged <- merge(students, scores, by = "id")
# dplyr join
library(dplyr)
merged <- inner_join(students, scores, by = "id")
Reading and writing data
# CSV
df <- read.csv("data.csv")
write.csv(df, "output.csv", row.names = FALSE)
# Excel (requires readxl)
library(readxl)
df <- read_excel("data.xlsx")
# R data format
save(df, file = "data.RData")
load("data.RData")
# JSON (requires jsonlite)
library(jsonlite)
df <- fromJSON("data.json")
toJSON(df)
tibbles — modern data frames
tibbles are tidyverse's enhanced data frames:
library(tibble)
df <- tibble(
name = c("Alice", "Bob"),
age = c(20, 22)
)
# Features
print(df) # shows first 10 rows
df$name # works (like data.frame)
df[["name"]] # also works
tibbles are stricter — they don't convert strings to factors, don't do partial matching, and display more nicely.
Mini Practice
- Create a data frame of five students with name, age, and grade columns
- Filter students with grade "A" using both base R and dplyr
- Add a new column that calculates age in months
- Use
summary()to get statistics for each column - Merge two data frames by a common ID column
Next: functions — reusable code →
Related Topics
Frequently Asked Questions about Data Frames
What is Data Frames in R?
Data Frames is a fundamental concept in R. This lesson explains it step by step with clear examples, making it easy for beginners to understand.
How do I learn Data Frames?
Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Data Frames.
Why is Data Frames important in R?
Data Frames is essential for R development. Understanding this concept will help you write better code and solve real-world problems more effectively.