100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Data Frames in R

Understand R's core tabular data structure — how data.frame combines vectors of equal length into rows and columns for real-world datasets.

Data StructuresBeginner9 min readJul 10, 2026
Analogies

What Is a Data Frame?

A data frame is R's primary structure for tabular data: internally it is a list of vectors of equal length, each vector forming one column, so a data frame can hold columns of different types (numeric, character, logical) side by side, unlike a matrix which requires a single uniform type. Rows correspond to observations and columns to variables, mirroring a spreadsheet or database table, and functions like str() and head() let you inspect structure and preview contents without printing the whole table.

🏏

Cricket analogy: A data frame recording an ODI match is like a scorecard table where each row is a player and columns hold runs, balls faced, and strike rate — different types sitting side by side, just as a data frame mixes column types.

Creating and Inspecting Data Frames

Data frames are built with data.frame(name = vector1, age = vector2, ...), where all supplied vectors must have equal length. str() prints a compact structure summary showing each column's type and first few values, summary() gives per-column statistics (mean, quartiles for numeric columns, counts for factors), and nrow()/ncol() or dim() report the table's dimensions, while colnames()/names() list the column labels.

🏏

Cricket analogy: Running str() on a match data frame is like glancing at a scoreboard's header row to confirm which columns are runs versus overs before analyzing the full innings.

r
students <- data.frame(
  name = c("Asha", "Ravi", "Meera"),
  age  = c(21, 23, 22),
  gpa  = c(8.7, 7.9, 9.1),
  stringsAsFactors = FALSE
)

str(students)
students$honors <- students$gpa > 8.5
students[students$age > 21, c("name", "gpa")]

Selecting Rows and Columns

Columns are accessed with the $ operator (df$age) or bracket notation (df[['age']] or df['age']), while general subsetting uses df[rows, columns] — for example df[df$age > 30, c('name','age')] returns only rows where age exceeds 30, keeping just the name and age columns. Leaving either the row or column position blank selects all of that dimension, so df[, 'name'] returns every row's name column and df[1:5, ] returns the first five rows with all columns.

🏏

Cricket analogy: df[df$runs > 50, ] filtering a scorecard data frame to only innings above fifty is like a commentator pulling up a highlights reel of every half-century in a series.

Since R 4.0.0, data.frame() no longer converts character columns to factors by default (stringsAsFactors = FALSE is now the default) — in older R versions or scripts targeting them, character columns silently became factors unless you set this argument explicitly.

Adding, Modifying, and Combining Data Frames

New columns are added simply by assignment, df$total <- df$runs + df$extras, which appends a column without altering existing ones. rbind() stacks data frames with matching column names on top of each other to add rows, cbind() binds columns side by side when row counts match, and merge() performs SQL-style joins between two data frames on a shared key column, supporting inner, left, right, and full joins via the all/all.x/all.y arguments.

🏏

Cricket analogy: rbind() stacking two innings data frames (first innings, second innings) into one match record is like combining two separate scorecards into a single Test match summary.

rbind() requires both data frames to have identical column names (order doesn't matter, but names must match) and compatible types — stacking a data frame with a column named 'Age' onto one with 'age' will error, and mismatched types (e.g., character vs. numeric) can silently coerce the whole column.

  • A data frame is a list of equal-length vectors, each column potentially a different type.
  • data.frame() builds one; str(), summary(), dim(), and colnames() inspect its structure.
  • Use df$col or df[['col']] for single columns, and df[rows, cols] for general subsetting.
  • Leaving a row or column index blank in df[rows, cols] selects all of that dimension.
  • rbind() stacks matching rows, cbind() binds matching columns, and merge() performs key-based joins.
  • Since R 4.0, strings stay character columns by default instead of becoming factors.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#RProgrammingStudyNotes#DataFramesInR#Data#Frames#Frame#Creating#StudyNotes#SkillVeris#ExamPrep