Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.
About EXL hiring for R Programming roles
EXL is a data analytics and digital operations company serving insurance, healthcare, banking and other industries. Its analytics teams build models for risk, marketing, collections and claims. In India it hires for business analysts, data analysts, data scientists and operations roles, many of them in insurance and banking analytics.
For R Programming roles, this EXL practice set focuses most on Statistics and Hypothesis Testing (6), Reports, Shiny and Production R (5), Functions and Functional Programming (4), Data Structures in R (4). It has 4 easy, 21 medium, 5 hard questions, so you can start easy and work up to the harder ones.
Company type
Analytics
Headquarters
New York, USA
Main India offices
Noida, Gurugram, Bengaluru, Pune
EXL R Programming interview process
Online assessment (aptitude + SQL or analytics)
Technical interview
Case or guesstimate round
HR round
Typical pattern based on public candidate experiences. Rounds vary by role, team and year.
Solved for EXLStart 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.
The tidyverse is a collection of R packages that share a common design and grammar for data science. Core packages include readr for importing, dplyr for transformation, tidyr for reshaping, ggplot2 for visualization, purrr for functional programming, stringr for text, forcats for factors and lubridate for dates. library(tidyverse) loads the core set. Its consistent function names and the pipe make analysis code readable, which is why most R analytics teams use it.
04
What are the differences between S3, S4 and R6 classes?
S3 is R's simplest object system: an object is a list with a class attribute, and generic functions like print() dispatch on it through UseMethod(). S4 adds formal class definitions with setClass(), typed slots and validity checks, and is common in Bioconductor. R6, from a package, provides reference semantics with mutable objects and encapsulated methods, similar to classes in Python or Java, and is used inside Shiny. Most analysis code needs only S3.
First I profile with profvis to find the slow lines. Then I try vectorizing, for example generating all random numbers at once with rnorm(n * reps) and using matrix operations instead of nested loops. I preallocate outputs instead of growing them. If iterations are independent, I run them in parallel with future and furrr. If a tight loop cannot be vectorized, I rewrite it in C++ with Rcpp, which often gives a 10 to 100 times speed-up.
07
Your R session runs out of memory while processing a large dataset. What steps do you take?
I check object sizes with lobstr::obj_size() and remove large intermediates with rm() followed by gc(). I load only the needed columns and use data.table, which modifies by reference without copies. For data larger than RAM, I push computation into a database through dbplyr, or use arrow with Parquet files so filters and aggregations run before data enters R memory. Chunked reading with readr::read_csv_chunked() is another option for one-pass jobs.
08
Tell me about a time you had two urgent analysis requests at the same time.
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.
09
How do you compare means across more than two groups in R?
Use one-way ANOVA, then a post-hoc test to see which pairs differ.
fit <- aov(sales ~ region, data = stores)
summary(fit) # overall F-test
TukeyHSD(fit) # pairwise comparisons
# check assumptions
plot(fit, which = 2) # Q-Q of residuals
bartlett.test(sales ~ region, data = stores)
# non-parametric alternative
kruskal.test(sales ~ region, data = stores)
10
What is the Central Limit Theorem and why is it important?
The Central Limit Theorem says that the distribution of sample means approaches a normal distribution as sample size grows, roughly beyond 30, regardless of the population's shape, provided observations are independent with finite variance. It is why t-tests, confidence intervals and A/B test calculations work on non-normal data such as order values. You can demonstrate it in R by repeatedly sampling from rexp() and plotting a histogram of the means.
Overfitting happens when a model learns noise in the training data, so it performs very well on training data but poorly on new data. Signs are a large gap between training and validation scores. Prevention includes using simpler models, regularization such as lasso or ridge, cross-validation for tuning, limiting tree depth, getting more data and removing leaky or irrelevant features. Underfitting is the opposite: the model is too simple to capture the pattern.
12
What is the difference between Pearson and Spearman correlation?
Pearson correlation measures the strength of a linear relationship between two numeric variables and is sensitive to outliers. Spearman correlation is computed on ranks, so it measures monotonic relationships and is robust to outliers and non-normal data. In R, cor(x, y, method = 'spearman') and cor.test() compute them. For example, ad spend and sales with diminishing returns may show a moderate Pearson value but a high Spearman value.
I would extract the logic into well-named functions with arguments for the parts that differ, then move them into one shared file loaded with source() or, better, a small internal R package. A package gives documentation with roxygen2, tests with testthat and versioning, so every script uses the same tested logic. Fixing a bug then happens in one place. I would migrate the scripts gradually and compare outputs to confirm nothing changed.
16
How would you impute missing values differently for each group?
I group by the relevant category, such as product category, and replace NAs with that group's median: group_by(category) %>% mutate(price = coalesce(price, median(price, na.rm = TRUE))) %>% ungroup(). Group medians are more realistic than a global value. I also add a flag column marking imputed rows so models and reviewers can see them. If a whole group is missing, I fall back to the overall median, and for important features I consider model-based imputation.
17
A manager says a test with p = 0.06 proves the change had no effect. How do you respond?
I explain that failing to reject the null is not proof of no effect. A p-value of 0.06 means the evidence is weak or the test was underpowered, and the 0.05 cut-off is a convention, not a law. I would show the confidence interval for the effect, which probably ranges from slightly negative to clearly positive, check whether the sample size met the planned power and suggest extending the test or weighing the decision on cost and risk.
18
Code reviews show inconsistent R code style across the team. How would you standardise it?
I would adopt the tidyverse style guide as the team standard, then automate it rather than relying on reviewers. styler reformats code automatically, including an RStudio add-in, and lintr flags issues such as long lines, unused variables and inconsistent naming. I add lintr to a pre-commit hook or a GitHub Actions check so pull requests are checked automatically. A short template for new scripts and projects helps new joiners follow the same structure.
19
How do you generate the same report for each of 20 regions automatically?
Use a parameterized Quarto or R Markdown report and render it in a loop.
# report.qmd header:
# params:
# region: 'North'
# then use params$region in the code
regions <- unique(sales$region)
purrr::walk(regions, function(r) {
quarto::quarto_render(
'report.qmd',
execute_params = list(region = r),
output_file = paste0('report_', r, '.html')
)
})
20
You need month-over-month sales growth for each product. How do you calculate it in R?
I first aggregate to one row per product and month with group_by() and summarise(). Then I group by product, arrange by month and use mutate(growth = (sales - lag(sales)) / lag(sales) * 100). The first month for each product becomes NA, which is correct. I make sure months with zero sales exist using tidyr::complete(), otherwise lag() compares non-consecutive months. Finally I round and format growth for reporting.
Situation: regional sales managers waited for a weekly emailed PDF and could not drill into their own data. Task: give them self-service access. Action: I built a Shiny app with filters by region, product and period, used pre-aggregated tables for speed and deployed it on the internal server with login. I ran a short demo and gathered feedback. Result: over 40 managers used it weekly, and ad hoc data requests to our team fell by about half.
22
Where do you see yourself in three years in an R or analytics career?
In three years I see myself as a strong data analyst or junior data scientist who can own analyses end to end, from understanding the business question to building reproducible reports and models in R. I want to deepen my statistics and machine learning skills and learn cloud tools used by the team. I would also like to mentor new joiners, as seniors helped me, and contribute to reusable internal tools.
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.
24
Tell me about feedback you received in a code review and what you changed.
Situation: in my first quarter, a senior reviewed my R reporting script. Task: address the review comments. Action: the main feedback was that my 300-line script mixed data loading, cleaning and plotting with repeated code. I split it into small functions, added input checks and moved constants to a config file. Result: the next report took half the time to build, and I now structure every new script this way from the start.
A Type I error is rejecting a true null hypothesis, a false positive, and its probability is the significance level alpha, usually 0.05. A Type II error is failing to reject a false null hypothesis, a false negative, with probability beta; power is 1 - beta. For example, launching a feature that does not actually help is a Type I error, while dropping a feature that really works is Type II. Larger samples reduce Type II errors.
26
Explain the d, p, q and r functions for probability distributions in R.
Each distribution has four functions: d for density, p for cumulative probability, q for quantiles and r for random draws.
dnorm(0) # density at 0
pnorm(1.96) # P(Z <= 1.96) = 0.975
qnorm(0.975) # 1.96
rnorm(5, mean = 50, sd = 10)
dbinom(3, size = 10, prob = 0.2) # exactly 3 successes
ppois(2, lambda = 4) # P(X <= 2)
qt(0.975, df = 20) # t critical value
27
What is a tibble and how does it differ from a base data frame?
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.
Common problems are a truncated y-axis on bar charts, which exaggerates differences because bar length should start at zero, inconsistent scales across panels, 3D effects, cherry-picked time ranges, dual axes with arbitrary ranges and too many colours. Area or bubble charts can mislead when size is mapped to radius instead of area. Good practice is to start bars at zero, label units, cite the data source and show context such as targets or prior periods.
29
Which chart types would you use for comparing categories, trends and distributions?
For comparing categories I use a bar chart, sorted by value, or a dot plot when there are many categories. For trends over time I use a line chart with time on the x-axis. For distributions I use histograms or density plots for one variable and boxplots or violin plots to compare groups. For relationships between two numeric variables I use a scatter plot. I avoid pie charts beyond three or four slices.
Measure before optimizing. system.time() gives total time, bench::mark() compares alternatives, and profvis shows which lines consume time and memory.
system.time(result <- slow_function(df))
bench::mark(
loop = sum_loop(x),
vec = sum(x)
)
library(profvis)
profvis({
out <- clean_data(raw)
model <- fit_model(out)
})
Tips to crack the EXL R Programming interview
Revise SQL, Excel and statistics such as hypothesis testing and regression, which are core to EXL analytics roles.
Practise guesstimates and simple business cases about credit card customers or insurance claims.
Learn insurance and banking analytics concepts like loss ratio, churn and collections propensity models.
Keep a one-minute story ready for every project on your CV: problem, your part, tools, result.
Practise the hard questions on this page aloud; EXL interviewers usually ask follow-ups on your first answer.
Frequently asked questions
How many rounds are there in the EXL R Programming interview?
Candidates usually go through 4 stages: Online assessment (aptitude + SQL or analytics); Technical interview; Case or guesstimate round; HR round. The exact rounds change with the role, team, location and your experience, so confirm the process with the recruiter.
Which topics should I prepare for the EXL R Programming interview?
This practice set leans on Statistics and Hypothesis Testing (6), Reports, Shiny and Production R (5), Functions and Functional Programming (4), Data Structures in R (4). Revise those first, then practise explaining one or two of your own projects end to end, because most EXL interviewers ask you to walk through real work.
Are these the exact questions asked at EXL?
No. These are curated practice questions that match the skills and difficulty usually tested in analytics interviews like EXL's. They are not a leaked or verified list of past questions.
Where does EXL hire R Programming professionals in India?
EXL has large teams in Noida, Gurugram, Bengaluru, Pune. Openings and locations change often, so check the EXL careers page and filter by city and experience.