Skip to content

Data Structures in R Interview Questions for R Programming

25 Data Structures in R questions with answers for r programming roles — 7 easy, 14 medium, 4 hard.

About Data Structures in R

R work revolves around vectors, lists, matrices, data frames and tibbles. This topic covers subsetting with [ ], [[ ]] and $, the apply family, strings, dates, data.table and list-columns. Interviewers test whether you can choose the right structure, index it correctly and combine many files or pieces efficiently without slow loops.

Sheet progressStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

What is the difference between a vector and a list in R?

Save to ▾
Show answer
An atomic vector holds elements of a single type, such as all numbers or all strings, while a list can hold elements of any type, including other lists, data frames or functions. c(1, 'a') coerces to character, but list(1, 'a', TRUE) keeps each type. Lists are used for nested data such as JSON responses and for returning multiple results from a function, which is why model objects like lm() output are lists.
02

What is a data frame in R?

Save to ▾
Show answer
A data frame is a list of equal-length vectors, where each vector is a column with its own type. It is R's main structure for tabular data, similar to a spreadsheet or SQL table. str(df) shows column types, nrow() and ncol() give dimensions and summary() gives quick statistics. Tibbles from the tidyverse are modern data frames that print neatly, never convert strings to factors and do not partially match column names.
03

How is a matrix different from a data frame?

Save to ▾
Show answer
A matrix is a two-dimensional atomic vector, so all elements share one type, usually numeric. A data frame allows a different type per column. Matrices are faster for linear algebra, such as %*% multiplication, solve() and distance calculations, while data frames suit mixed real-world data. For example, the output of cor() is a matrix, while customer records with names, dates and amounts belong in a data frame. as.matrix() and as.data.frame() convert between them.
04

Show different ways to index vectors and data frames in R.

Save to ▾
Show answer
R indexes from 1 and supports positive, negative, logical and name-based indexing. x <- c(a = 10, b = 20, c = 30, d = 40) x[2] # 20 x[-1] # drop first x[c('a', 'd')] # by name x[x > 15] # logical filter which(x > 15) # positions df[df$age > 30, c('name', 'city')] df[order(-df$salary), ][1:5, ] # top 5 salaries
05

Dates in your file look like 25/12/2025 and as.Date() returns NA. What is wrong and how do you fix it?

Save to ▾
Show answer
Indian files often store dates as dd/mm/yyyy, but as.Date() expects yyyy-mm-dd by default, so values become NA. I specify the format, as.Date(x, format = '%d/%m/%Y'), or use lubridate::dmy(x), which handles different separators automatically. Then I count NAs before and after conversion to confirm nothing failed silently. If the column came from Excel as serial numbers, I use as.Date(x, origin = '1899-12-30') instead.
06

What is an array in R?

Save to ▾
Show answer
An array is a multi-dimensional generalization of a matrix, created with array(data, dim = c(rows, cols, layers)). All elements share one type. For example, array(1:24, dim = c(2, 3, 4)) has four layers of 2 by 3 matrices, and you index with arr[1, 2, 3]. Arrays are used for image data, simulation outputs and time by region by product cubes, though for business analysis long-format data frames are usually easier to work with.
07

How do you explain technical results to non-technical managers?

Save to ▾
Show answer
I start with the business question and the answer in one sentence, then show one or two clear charts instead of tables of coefficients. For example, in a college project on customer churn, I said that customers with more than three complaints were twice as likely to leave, showed a simple bar chart and suggested a follow-up call process. I keep technical details in an appendix and invite questions so managers can decide confidently.
08

What is the difference between [ ], [[ ]] and $ when subsetting?

Save to ▾
Show answer
For lists, [ ] returns a sub-list, while [[ ]] and $ return the element itself. So lst['a'] is a list of length one and lst[['a']] is the value. $ allows partial name matching and cannot take a variable, while [[ ]] accepts a string variable like lst[[col]]. On data frames, df['x'] returns a one-column data frame, and df[['x']] or df$x returns a vector. Think of [ ] as the train car and [[ ]] as its contents.
09

What does drop = FALSE do when subsetting?

Save to ▾
Show answer
When you subset a single column or row from a matrix or base data frame with [ ], R simplifies the result to a vector by default. Writing m[, 1, drop = FALSE] keeps it as a matrix or data frame. This matters inside functions, because code expecting a data frame breaks when a selection leaves only one column. Tibbles never drop dimensions, which is one reason developers prefer them in reusable code and packages.
10

Explain the apply family of functions in R.

Save to ▾
Show answer
apply() works over rows or columns of a matrix, lapply() applies a function to each element of a list and returns a list, sapply() simplifies the result to a vector or matrix when possible, vapply() is like sapply() but requires a declared output type, making it safer, and mapply() iterates over several vectors in parallel. tapply() applies a function by groups. For example, sapply(df, class) returns the class of each column.
11

How do you create, modify and combine lists in R?

Save to ▾
Show answer
Lists are built with list(), modified by name and combined or flattened when needed. emp <- list(name = 'Asha', skills = c('R', 'SQL'), exp = 3) emp$city <- 'Pune' # add element emp[['exp']] <- 4 # update emp$skills <- NULL # remove names(emp) parts <- lapply(1:3, function(i) data.frame(id = i, sq = i^2)) do.call(rbind, parts) # combine data frames unlist(list(a = 1, b = list(c = 2))) # flatten
12

You receive 60 monthly CSV files with the same structure. How do you combine them into one data frame?

Save to ▾
Show answer
I list the files with list.files(pattern = 'csv$', full.names = TRUE), then read them all at once with readr::read_csv(files, id = 'file'), which also records the source file. Alternatively I use purrr::map() with read_csv and dplyr::bind_rows(). Before combining, I check that column names and types match, because one file with text in a numeric column will fail or coerce the whole column. I then derive the month from the file name for traceability.
13

A loop that adds rows to a data frame with rbind() takes very long. How do you speed it up?

Save to ▾
Show answer
Calling rbind() inside a loop copies the growing data frame each iteration, so time grows roughly quadratically. I instead store each piece in a preallocated list, results[[i]] <- piece, and combine once at the end with dplyr::bind_rows() or data.table::rbindlist(), which is the fastest. Better still is to vectorize the computation or use purrr::map() followed by list_rbind(). On 10,000 iterations this can cut runtime from minutes to seconds.
14

What is a tibble and how does it differ from a base data frame?

Save to ▾
Show answer
A tibble is the tidyverse version of a data frame. It prints only the rows and columns that fit the screen along with column types, never converts strings to factors, never changes column names, does not partially match with $ and always returns a tibble when subsetting with [ ]. It also supports list-columns easily. You convert with as_tibble(). Tibbles prevent many silent bugs, though some older packages expect base data frames.
15

What is data.table and when would you use it?

Save to ▾
Show answer
data.table is a high-performance package for large tabular data. Its syntax DT[i, j, by] means filter rows with i, compute j, grouped by by. It updates columns by reference with :=, avoiding copies, and offers fast keyed joins and fread()/fwrite() for file IO. For example, DT[city == 'Delhi', .(avg_sal = mean(salary)), by = dept] filters and aggregates in one step. It is popular for datasets with tens of millions of rows.
16

Write common data.table operations for filtering, aggregating and joining.

Save to ▾
Show answer
Read, filter, aggregate, add columns by reference and join: library(data.table) DT <- fread('orders.csv') DT[status == 'delivered', .N, by = city] DT[, revenue := qty * price] DT[, .(total = sum(revenue)), by = .(city, month)][order(-total)] customers <- fread('customers.csv') merged <- customers[DT, on = 'customer_id'] fwrite(merged, 'merged.csv')
17

How do you clean and manipulate text data in R?

Save to ▾
Show answer
The stringr package gives consistent functions starting with str_. library(stringr) x <- c(' Rahul Sharma ', 'priya VERMA') str_trim(x) str_to_title(x) str_detect(x, 'Sharma') str_replace_all('9876-543-210', '-', '') str_extract('Order ID: 45821', '[0-9]+') str_split('a,b,c', ',')[[1]] str_pad('7', width = 3, pad = '0') # '007'
18

How are dates and times handled in R?

Save to ▾
Show answer
Base R stores dates as the Date class, counting days since 1970-01-01, and date-times as POSIXct, counting seconds. as.Date('2026-03-15') parses ISO strings and format() controls output. The lubridate package simplifies parsing with ymd(), dmy() and mdy(), extracting parts with month() and wday(), and arithmetic like date + months(1). Time zones matter: Indian data usually uses 'Asia/Kolkata', and mixing UTC with IST can shift records across days.
19

After merging two data frames you get more rows than expected. What happened?

Save to ▾
Show answer
Extra rows after a join usually mean the key is duplicated in one or both tables, so each match multiplies rows. I check uniqueness with df %>% count(key) %>% filter(n > 1) on both sides. Then I decide whether to deduplicate, aggregate before joining or join on a composite key such as customer_id plus month. In dplyr 1.1 and later, the relationship argument, for example 'many-to-one', makes the join fail loudly when this assumption breaks.
20

Describe a time you found a data quality issue in your analysis.

Save to ▾
Show answer
Situation: while preparing a monthly revenue dashboard, totals were 8 percent higher than finance figures. Task: find the cause before the review meeting. Action: I traced row counts after each step in my R script and found a join on customer ID that duplicated rows because some customers had two active addresses. I deduplicated the address table and added a row-count check. Result: numbers matched finance, and the check now runs in every refresh.
21

Tell me about a time you had two urgent analysis requests at the same time.

Save to ▾
Show answer
Situation: two managers needed different analyses on the same Friday. Task: deliver both without compromising quality. Action: I asked each what decision the analysis would support and the minimum needed by Friday, reused one cleaned dataset in R for both, and shared a draft of the simpler one on Wednesday for early feedback. Result: both received usable outputs on time, and the fuller version of the second analysis followed on Monday as agreed.
22

What is a list-column and why is it useful?

Save to ▾
Show answer
A list-column is a data frame column whose cells are lists, such as nested data frames or fitted models. With tidyr::nest() you group data, for example by region, into a column of sub-data frames, then use purrr::map() to fit a model per region and broom::tidy() to extract coefficients. This keeps data, models and results aligned row by row, which is cleaner than managing separate lists of models and names.
23

Write code to fit one regression model per group using nested data.

Save to ▾
Show answer
Fit one model per region with list-columns: library(dplyr); library(tidyr) library(purrr); library(broom) models <- sales %>% group_by(region) %>% nest() %>% mutate( fit = map(data, ~ lm(revenue ~ ad_spend, data = .x)), coefs = map(fit, tidy), r2 = map_dbl(fit, ~ glance(.x)$r.squared) ) models %>% unnest(coefs) %>% select(region, term, estimate)
24

Are factors more memory efficient than character vectors in modern R?

Save to ▾
Show answer
Not by much. R keeps a global string pool, so each unique string is stored once and a character vector only holds pointers, which makes repeated values already compact. Factors still matter for controlling level order in plots and models and for representing a fixed set of categories. For huge data, data.table and arrow handle strings efficiently, and converting high-cardinality IDs to factors usually adds overhead without any benefit.
25

An API returns deeply nested JSON. How do you turn it into a tidy data frame in R?

Save to ▾
Show answer
I make the request with httr2, handling authentication and pagination, then parse with jsonlite::fromJSON(), which simplifies arrays of objects into data frames, using flatten = TRUE to spread nested objects into columns. For deeper nesting I keep a list and use tidyr::unnest_wider() and unnest_longer() to expand list-columns step by step. Optional keys become NA, so I check missing fields across records and validate types before analysis.

Frequently asked questions

How important is Data Structures in R in R Programming interviews?

R work revolves around vectors, lists, matrices, data frames and tibbles. This topic covers subsetting with [ ], [[ ]] and $, the apply family, strings, dates, data.table and list-columns. Interviewers test whether you can choose the right structure, index it correctly and combine many files or pieces efficiently without slow loops.

How should I use the Data Structures in R sheet?

Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.