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.
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
1. What must be true of the vectors passed to data.frame()?
2. Which expression selects only the 'age' column from data frame df?
3. What does df[df$score > 90, ] return?
4. Which function joins two data frames on a shared key column?
5. Since R 4.0.0, what is the default behavior of data.frame() for character columns?
Was this page helpful?
You May Also Like
Vectors in R
Learn how R's core data structure — the atomic vector — stores, indexes, and vectorizes operations over ordered collections of same-typed values.
Lists and Matrices in R
Compare R's two other core structures — the flexible, heterogeneous list and the strict, two-dimensional matrix — and learn when to use each.
Factors in R
Learn how R represents categorical data with factors — encoding fixed levels efficiently and controlling ordinal comparisons.
Data Import and Export in R
Master reading and writing common file formats in R — CSV, Excel, and RDS — and know which function fits which situation.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics