☰

Top 48 R Interview Questions and Answers

R Programming Interview Questions and Answers

R interviews test two things: whether you know the language well enough to avoid its common traps, and whether you can turn data into a clear result. This guide gives you 48 R interview questions and answers, from basics to scenario questions, for freshers and experienced analysts.

Every answer starts with a short, direct response you can say aloud, followed by a table or a code sample with its output. The page covers modern R, with the native pipe, tidyverse, ggplot2, Quarto and tidymodels, and keeps base R where interviewers still ask for it.

The guide has seven parts: 10 on R basics, 9 on functions and the apply family, 8 on data manipulation and the tidyverse, 5 on visualisation and reporting, 5 on statistics and modelling, 6 on advanced R and performance and 5 scenario questions. Use the contents list to jump to your level.

Key points

  • 48 questions in seven parts, from basics to scenarios.
  • Modern R: native pipe, tidyverse, Quarto and tidymodels.
  • Common traps explained: NA, recycling, factors and floating point.
  • Comparison tables for data structures, apply functions, joins and data frame types.
  • Scenario answers for reproducibility, joins and large files.

In this guide

What this guide covers
Section Questions
R Basics (Freshers) Q1 to Q10
Functions, Control Flow and the Apply Family (Intermediate) Q11 to Q19
Data Manipulation, Import and Tidyverse (Intermediate) Q20 to Q27
Visualisation and Reporting (Intermediate) Q28 to Q32
Statistics and Modelling in R (Intermediate and Experienced) Q33 to Q37
Advanced R and Performance (Experienced) Q38 to Q43
Scenario Questions (Experienced) Q44 to Q48

R Basics (Freshers)

Start with what R is, its data structures and how it handles missing values. Most R interviews begin here, and small details such as recycling and NA are common traps.

Q1. What is R, and what is it used for?

R is an open source language and environment for statistical computing, data analysis and graphics. It is used for data cleaning, statistical modelling, visualisation, reporting and increasingly machine learning. Its strength is the package ecosystem on CRAN, which holds more than 20,000 packages, and a very strong community in statistics, research, healthcare and finance.

What the interviewer is listening for: You can name where R is strongest, which is statistics and reporting, without running down other languages.

Q2. What are the basic data types in R?

The atomic types are logical, integer, numeric (double), complex, character and raw. A numeric literal such as 5 is a double by default, and you add an L, as in 5L, to get an integer. Use class() to see the type a user would think of, and typeof() for the storage type.

r
class(1:3)
typeof(1)
class("text")
class(TRUE)
output
[1] "integer"
[1] "double"
[1] "character"
[1] "logical"

 

Q3. What are the main data structures in R?

The main structures are the vector, matrix, array, list, data frame and factor. A vector holds values of one type. A matrix is a two dimensional vector. A list can hold items of different types. A data frame is a list of equal length columns, and a factor stores categories as integer codes with labels.

Core data structures in R
Structure Dimensions Holds
Vector 1 One type only
Matrix 2 One type only
Array n One type only
List 1 Mixed types, including other lists
Data frame 2 Columns of different types, equal length
Factor 1 Categories stored as integers with levels

 

Q4. What is the difference between a list and a vector?

A vector holds elements of a single type, so mixing types coerces them to the most general one. A list can hold elements of different types and lengths, including vectors, functions and other lists. Use single brackets to get a sub list and double brackets to extract the element itself.

Q5. What is a data frame, and how does it differ from a matrix?

A data frame is a table where each column is a vector of one type, and columns can differ in type, so it fits real datasets with numbers, text and dates. A matrix has one type for every cell. Data frames are the standard structure for analysis, and the tibble is the tidyverse version.

Q6. What is a factor, and when would you use one?

A factor represents a categorical variable. R stores it as integer codes with a set of labels called levels. Use factors for groups in models and plots, and for ordered categories such as low, medium and high. Since R 4.0, text columns are no longer converted to factors by default.

r
f <- factor(c("low", "high", "low"))

levels(f)
as.integer(f)
output
[1] "high" "low"
[1] 2 1 2

 

Levels are sorted alphabetically by default, so high comes before low. Set the levels argument to control the order.

Q7. How does R handle missing values?

R uses NA for a missing value, and any calculation involving NA returns NA unless you tell it to skip. Most summary functions accept na.rm = TRUE. Test for missing values with is.na(), never with equality, because NA == NA is also NA. NULL is different: it means no object at all.

r
x <- c(10, 20, NA)

mean(x)
mean(x, na.rm = TRUE)
is.na(x)
output
[1] NA
[1] 15
[1] FALSE FALSE  TRUE

 

Q8. What is the difference between NULL, NA and NaN?

NA marks a missing value of some type. NaN means not a number and comes from an undefined calculation such as 0 divided by 0. NULL is the empty object with length zero, often returned by functions that find nothing. is.na() is true for both NA and NaN, while is.nan() is true only for NaN.

NA, NaN and NULL in R
Value Meaning Length
NA Missing value 1
NaN Undefined number, such as 0 divided by 0 1
NULL No object at all 0

 

Q9. What is vector recycling?

When two vectors of different lengths are combined in an operation, R repeats the shorter one until it matches the longer one. If the longer length is not a multiple of the shorter, R gives a warning. Recycling is convenient but a common source of silent bugs, so check the lengths.

r
1:6 + 1:2
output
[1] 2 4 4 6 6 8

 

Q10. Why does 0.1 + 0.2 not equal 0.3 in R?

Computers store decimals in binary floating point, so 0.1 and 0.2 are stored as close approximations, and their sum differs from 0.3 by a tiny amount. Compare numbers with all.equal() wrapped in isTRUE(), which allows a small tolerance, and not with the double equals sign.

r
identical(0.1 + 0.2, 0.3)

isTRUE(all.equal(0.1 + 0.2, 0.3))
output
[1] FALSE
[1] TRUE

 

Functions, Control Flow and the Apply Family (Intermediate)

These questions test whether you write R the way R is meant to be written: vectorised, with small functions and without unneeded loops.

Q11. How do you write a function in R?

Use the function keyword, give it arguments with optional defaults, and write the body. R returns the value of the last expression, so an explicit return() is optional. Since R 4.1 you can write short anonymous functions with a backslash, as in \(x) x + 1.

r
area <- function(width, height = 1) {
  width * height
}

area(4)
area(4, 3)

sq <- \(x) x^2
sq(5)
output
[1] 4
[1] 12
[1] 25

 

Q12. What does vectorisation mean, and why is it important?

Vectorisation means an operation is applied to every element of a vector at once, without writing a loop. Vectorised code is shorter and faster, because the loop runs in compiled code. Prefer x * 2 to a for loop over x, and use ifelse() instead of an if inside a loop.

r
c(1, 2, 3) * 2

ifelse(c(5, 15, 25) > 10, "high", "low")
output
[1] 2 4 6
[1] "low"  "high" "high"

 

Q13. What is the difference between apply, lapply, sapply and vapply?

The apply function works over the rows or columns of a matrix. The lapply function loops over a list or vector and always returns a list. The sapply function does the same but simplifies the result to a vector or matrix when it can. The vapply function is the safer form, because you state the expected type.

The apply family in R
Function Works on Returns
apply Matrix rows or columns Vector, matrix or list
lapply List or vector Always a list
sapply List or vector Simplified vector or matrix
vapply List or vector Vector of a type you declare
tapply Vector grouped by a factor Array of group results
mapply Several vectors in parallel Simplified vector or list
r
sapply(1:3, function(i) i^2)
vapply(1:3, function(i) i^2, numeric(1))
output
[1] 1 4 9
[1] 1 4 9

 

Q14. When would you prefer a for loop to an apply function?

Use a loop when each step depends on the previous result, when you modify an object step by step, or when the logic has side effects such as writing files. Otherwise prefer vectorised code or the apply family. A loop itself is not slow in R. The usual slowness comes from growing an object inside the loop.

Pre allocate the result with vector or numeric of the final length before the loop, and fill it by index.

Q15. How do you find the column with the largest value in each row of a matrix?

Use max.col(), which returns the column index of the maximum in each row. Ties are broken at random by default, so set ties.method to first for a repeatable result. The apply function with which.max also works. Note that the function is max.col, and there is no function called col.max.

r
m <- matrix(c(1, 9, 3,
              8, 2, 7), nrow = 2, byrow = TRUE)

max.col(m)
apply(m, 1, which.max)
output
[1] 2 1
[1] 2 1

 

Q16. What is lazy evaluation in R?

R evaluates a function argument only when the function first uses it. So an argument that is never used is never evaluated, and a default value can refer to another argument. It enables tools such as substitute() and non standard evaluation, which the tidyverse relies on. It can also delay an error until the argument is used.

Q17. What is the difference between = and <- for assignment?

Both assign a value at the top level, but the arrow is the convention in R code and works everywhere. The equals sign is used to set function arguments, such as mean(x, na.rm = TRUE). Inside a function call, an arrow creates a variable in the calling environment, so mixing them can surprise you.

Q18. What are environments and scoping rules in R?

An environment is a set of names bound to values. R uses lexical scoping, meaning a function looks for a variable first in its own environment and then in the environment where it was defined, up to the global environment. The double arrow assigns to a variable in an enclosing environment, and is best avoided.

Q19. What is the native pipe, and how does it differ from the magrittr pipe?

The native pipe, written as |>, arrived in R 4.1 and passes the left side as the first argument of the function on the right. The magrittr pipe, written as %>%, is from a package and allows a dot placeholder and more flexibility. Since R 4.2, the native pipe also supports an underscore placeholder for a named argument.

r
mtcars |> subset(cyl == 4) |> nrow()
output
[1] 11

 

Data Manipulation, Import and Tidyverse (Intermediate)

Most daily R work is cleaning and reshaping data. Know both base R and the tidyverse and be able to say when you use each.

Q20. How do you import and export data in R?

Use read.csv and write.csv in base R, or readr functions such as read_csv for faster, more predictable reading. For Excel use readxl, and for databases use DBI with a driver. Large files read quickly with data.table fread or the arrow package. Always check column types after import.

r
library(readr)

sales <- read_csv("data/sales.csv")
glimpse(sales)

 

Q21. What are the main dplyr verbs?

The core verbs are filter for rows, select for columns, mutate for new columns, arrange for sorting, summarise for collapsing and group_by to apply the others by group. They are chained with a pipe so the code reads in the order of the steps.

r
library(dplyr)

mtcars |>
  filter(cyl == 4) |>
  group_by(gear) |>
  summarise(avg_mpg = mean(mpg), n = n())

 

Q22. How do you join two data frames in R?

In dplyr use left_join, inner_join, right_join, full_join, semi_join and anti_join with a by argument naming the key. In base R use merge(). A left join keeps all rows of the left table, and an anti join returns the rows of the left table with no match, which is useful for finding gaps.

dplyr joins and what each keeps
Join Keeps
inner_join Only rows with a match in both
left_join All rows from the left, matched rows from the right
right_join All rows from the right, matched rows from the left
full_join All rows from both
anti_join Left rows with no match on the right

 

Q23. What is tidy data, and how do you reshape it?

Tidy data has one variable per column, one observation per row and one value per cell. Use pivot_longer from tidyr to turn wide data into long data, and pivot_wider for the reverse. Tidy data makes grouping, plotting and modelling simpler, and the older gather and spread functions are superseded.

Q24. How do you handle missing data in a data frame?

First measure it with colSums(is.na(df)) to see the count in each column. Then decide: drop rows with na.omit or tidyr drop_na, fill values with replace_na or a model based imputation, or keep NA where it carries meaning. Record the choice, since each one changes the result.

r
colSums(is.na(df))

df |> tidyr::drop_na(age)

df |> dplyr::mutate(income = tidyr::replace_na(income, median(income, na.rm = TRUE)))

 

Q25. What is the difference between data.frame, tibble and data.table?

A data.frame is the base R structure. A tibble is the tidyverse version that prints neatly, never changes column names or types silently and does not use row names. A data.table is a fast, memory efficient extension with a compact syntax, and it suits very large data. They convert easily to each other.

data.frame, tibble and data.table compared
Type Strength Typical use
data.frame Built in, universal Basic analysis and compatibility
tibble Safer printing and subsetting Tidyverse workflows
data.table Speed and low memory use Millions of rows

 

Q26. How do you work with dates in R?

The Date class holds calendar dates and POSIXct holds date times. Use as.Date with a format, or the lubridate package with functions such as ymd and dmy, which are easier to read. You can add days, extract months and compute the difference between dates directly.

r
library(lubridate)

d <- ymd("2026-03-15")
d + 30
month(d)

 

Q27. How do you remove duplicate rows?

Use distinct() from dplyr to drop fully duplicated rows, or give it columns to deduplicate on, with the keep all argument to retain the other columns. In base R, use df[!duplicated(df), ]. Check duplicates first with count or duplicated, since a duplicate can signal a join or key problem.

Visualisation and Reporting (Intermediate)

Be ready to describe a chart you built and the reason for each choice.

Q28. How does ggplot2 work?

ggplot2 builds a chart in layers using the grammar of graphics. You supply data, map columns to aesthetics such as x, y and colour, add geometries such as points or bars, and then add scales, labels and themes with the plus sign. It makes complex charts consistent and easy to modify.

r
library(ggplot2)

ggplot(mtcars, aes(x = wt, y = mpg, colour = factor(cyl))) +
  geom_point() +
  labs(x = "Weight", y = "Miles per gallon", colour = "Cylinders")

 

Q29. What is the difference between base R graphics and ggplot2?

Base graphics draw directly on a device step by step, which is quick for simple plots but harder to keep consistent. ggplot2 describes the chart as a whole and handles legends, scales and grouping automatically. Most teams use ggplot2 for reports and base plots for quick checks.

Q30. How do you choose a chart type?

Pick by the question. Use a bar chart to compare categories, a line chart for change over time, a histogram or box plot for a distribution, and a scatter plot for the relationship between two numbers. Avoid pie charts with many slices, and label axes clearly.

Q31. What is R Markdown or Quarto, and why use it?

R Markdown and its successor Quarto combine text, code and output in a single document, which can be rendered to HTML, PDF or Word. They make analysis reproducible, because the report is regenerated from the data and code. Parameters let you produce many reports from one template.

Q32. What is Shiny?

Shiny is an R package for building interactive web applications without writing HTML or JavaScript. An app has a user interface and a server function, and outputs update automatically when inputs change, a pattern called reactivity. Shiny is used for dashboards and internal analysis tools.

Statistics and Modelling in R (Intermediate and Experienced)

Expect to be asked to fit a model and explain the output, not only to name the function.

Q33. How do you fit and interpret a linear regression in R?

Use lm() with a formula, and call summary() on the result. The summary shows coefficients with standard errors and p values, the R squared and the residual standard error. A coefficient is the expected change in the outcome for a one unit rise in that predictor, holding the others constant.

r
fit <- lm(mpg ~ wt + hp, data = mtcars)

summary(fit)
confint(fit)

 

Q34. How do you run a t test and interpret it?

Use t.test() with two samples or a formula. It returns the test statistic, degrees of freedom, p value and a confidence interval for the difference. A small p value means the observed difference would be unusual if the true means were equal. Check assumptions of roughly normal data and, for the default, unequal variances.

r
t.test(mpg ~ am, data = mtcars)

 

Q35. How do you fit a logistic regression?

Use glm() with family = binomial. The coefficients are on the log odds scale, so exponentiate them to get odds ratios. Use predict with type = “response” to get probabilities, and judge the model with a confusion matrix, ROC curve and area under the curve at a sensible threshold.

r
fit <- glm(am ~ wt + hp, data = mtcars, family = binomial)

exp(coef(fit))
head(predict(fit, type = "response"))

 

Q36. How do you split data and evaluate a model in R?

Split the data into training and test sets, fit on the training set and measure error on the test set. With the tidymodels framework, rsample makes the split and resamples, parsnip defines the model, and yardstick computes metrics. Use cross validation to get a more stable estimate and set a seed so results repeat.

r
library(tidymodels)

set.seed(42)
split <- initial_split(mtcars, prop = 0.8)
train <- training(split)
test  <- testing(split)

 

Q37. What is the difference between the caret and tidymodels packages?

Both give one interface to many modelling methods and help with tuning and resampling. The caret package is older and stable. The tidymodels framework is the newer, modular successor from the same team, built around the tidyverse. New projects usually choose tidymodels, while many existing codebases still use caret.

Advanced R and Performance (Experienced)

Experienced candidates are asked about speed, memory and writing code others can maintain.

Q38. How do you make slow R code faster?

Measure first with profvis or the bench package, then fix the biggest cost. Vectorise loops, pre allocate results, avoid growing objects, and use data.table or dplyr with a database backend for large data. Move a hot loop to C++ with Rcpp, or run independent tasks in parallel with the future or parallel packages.

  • Profile before changing anything.
  • Avoid copying large objects inside loops.
  • Read only the columns you need.

Q39. How does R manage memory, and what do you do with data larger than memory?

R keeps objects in memory, and copies an object when it is modified under some conditions, so large data can run out of memory. Options are to read less data, use data.table or arrow with Parquet files, query a database and bring back only the summary, or use a disk based approach such as duckdb.

Q40. What are S3, S4 and R6 classes?

They are object systems in R. S3 is informal and based on generic functions and a class attribute, and is the most common. S4 is formal, with defined slots and validity checks. R6 gives reference semantics like classes in other languages, so objects can be changed in place. Choose S3 for simple needs.

Q41. How do you manage packages and make a project reproducible?

Use an R project for each analysis, store code in version control and record package versions with renv, which creates a lockfile that restores the same versions on another machine. Set seeds for random work, avoid absolute paths and keep raw data unchanged. Quarto makes the report rerunnable end to end.

Q42. How do you create an R package?

Use usethis and devtools to create the structure, write functions in the R folder with roxygen comments for documentation, add tests with testthat, and check with devtools check. A package makes your code shareable, testable and installable, and it forces a clear description of dependencies.

Q43. How do you connect R to a database?

Use the DBI package with a driver for the database, such as RPostgres or odbc. Write SQL directly, or use dplyr with dbplyr, which translates your pipeline into SQL and runs it in the database. This keeps heavy work in the database and brings back only the results.

Scenario Questions (Experienced)

Explain how you would approach the problem, what you would check and how you would confirm the answer.

Q44. Your script worked yesterday but gives different results today. What do you check?

Check what changed: the input data, package versions, the R version, random seeds and the working directory. Compare row counts and a checksum of the input. Restore the exact package versions from the renv lockfile and rerun. Set a seed for any random step. Then add tests so the change is caught next time.

Q45. A join gives more rows than the left table. Why, and how do you fix it?

The right table has duplicate keys, so each left row matches several rows. Count the keys with count() to confirm, then deduplicate the right table, add the missing key column, or aggregate before joining. Dplyr gives a warning on many to many joins, so read it. Add a check on row counts after each join.

Q46. A report must run every Monday with fresh data. How do you set it up?

Write the analysis in a Quarto document with parameters, store data access in a function with credentials held in environment variables, and lock packages with renv. Schedule the render with cron or a scheduler such as Posit Connect, send the output by email or publish it, and add a failure alert and a data check.

Q47. You must analyse a 20 GB file on a 16 GB laptop. What do you do?

Do not read it all at once. Convert it to Parquet, then query it with arrow or duckdb, which process data in chunks and push filters down to the file. Select only the needed columns, aggregate in the engine and collect only the summary into R. Sample the data first to develop the code.

Q48. A stakeholder asks you to explain a regression result to a non technical audience. How do you do it?

State the finding in plain words, with the effect size and its uncertainty, for example that each extra year of experience is linked to about this much higher salary, give or take a range. Say what the model cannot show, such as cause. Use one clear chart in place of a table of coefficients.

What the interviewer is listening for: You focus on the decision, give a range and not just one number, and you mention the limits.

Common questions about R interviews

What topics should I prepare for an R interview?

Prepare data structures, missing values, vectorisation and the apply family first. Then learn dplyr and tidyr, ggplot2, joins, dates and importing data. Add regression, t tests and logistic regression, and reporting with Quarto. Experienced roles add performance, packages and reproducibility.

Should I learn R or Python for data analysis?

Learn the one your target employers use. R is strong in statistics, research, healthcare and reporting. Python is stronger for engineering and machine learning pipelines. Many analysts know both, and the ideas such as tidy data and model evaluation transfer between them. Check the job descriptions you are aiming for.

Which R version and IDE should I use?

Use the current R release, which is 4.6.1 at the time of writing, and RStudio or Positron as the editor. Install packages from CRAN, and use Quarto for reports. Check the official R and Posit pages for the latest versions.

Is the tidyverse enough, or do I need base R?

Learn both. Interviewers often ask base R questions such as apply, subsetting and factors, while daily work uses the tidyverse. Being able to read old base R code is valuable, and knowing the tidyverse makes your own code easier to read.

How can I practise R without a project at work?

Use public datasets, such as government open data, and build a small analysis from import to a report. Publish the Quarto output with the code on GitHub, since interviewers ask to see it. Redo one analysis in a second way to practise the alternative approach.

A four week plan to prepare

Use this plan if you have about a month before your interview.

Four week study plan
Week Focus What to do
Week 1 R basics Practise vectors, lists, data frames, factors, NA and recycling in short scripts.
Week 2 Data manipulation Clean a real dataset with dplyr and tidyr, join two tables and reshape one.
Week 3 Visualisation and modelling Build five ggplot2 charts and fit a linear and a logistic regression, explaining each output.
Week 4 Advanced and scenarios Profile slow code, set up renv and practise the scenario questions aloud.

 

Practise with a trainer

If you want to practise these questions with a trainer and work on hands on projects, you can book a free demo class for the Prwatech Data Science course. It covers R, statistics, machine learning and hands on projects.

Contact the learning team for current batch dates and fees.

Written by Mithun Ray, data engineering trainer at Prwatech. Reviewed by Avishekh Verma. Last updated October,2026.

Popular Tags:

R Interview Questions and Answers