In short
R is a free, open-source language and environment built specifically for statistical computing and graphics, distributed through CRAN with more than 20,000 contributed packages. Everything in R is an object and almost every operation is vectorised, so a whole column is processed in one expression instead of a loop. Indian B.Sc/M.Sc Statistics syllabuses (UGC CBCS) examine R in a compulsory practical paper — descriptive statistics, plots, distributions, testing of hypotheses, regression and ANOVA done on the console with output interpreted. It is used in pharma CROs and clinical trials, market research, credit risk and analytics teams at Indian banks, ICMR/NIE research, MoSPI and NSS survey analysis, and is a standard screening topic in data-analyst interviews.
Explained
The environment, objects and modes
- R is interpreted, works from a console (or RStudio IDE); scripts are
.Rfiles, reproducible reports are.Rmd/Quarto. - Assignment uses
<-(preferred) or=;#starts a comment; statements need no semicolon. - Atomic modes:
logical,integer,double(numeric),complex,character.class()gives the class,typeof()the storage type,str()the structure. - Special values:
NA(missing),NULL(empty object),NaN(0/0),Inf/-Inf.NAis contagious —mean(x)isNAunless you writemean(x, na.rm = TRUE). - Coercion hierarchy: logical → integer → double → character.
c(1, "a", TRUE)becomes all character. - Workspace commands:
ls(),rm(x),getwd(),setwd(),save.image(),help(mean)or?mean,install.packages(),library(). - Indexing is 1-based (not 0-based as in C/Python) and
x[-1]means "drop the first element", not "last element".
Data structures (the standard exam list)
- Vector — one-dimensional, single mode:
c(),seq(1, 10, by = 2),rep(0, 5),1:10. Elements can be named. - Recycling rule: in
c(1,2,3,4) + c(10,20)the shorter vector repeats →11 22 13 24. A warning appears only if lengths are not multiples. - Matrix — two-dimensional, single mode:
matrix(1:6, nrow = 2)fills column-wise unlessbyrow = TRUE. Operations:t(),%*%(matrix product),solve()(inverse / solving equations),det(),diag(),dim(),rbind(),cbind(),eigen(). - Array — three or more dimensions.
- List — ordered collection of *any* objects of any type; accessed by
[[ ]]or$. Most modelling functions return lists. - Data frame — a list of equal-length vectors shown as a table: the standard form for a dataset, rows = observations, columns = variables.
nrow(),ncol(),names(),head(),df$col,df[2, 3],subset(). - Factor — a categorical variable stored as integer codes with a
levelsattribute;ordered = TRUEfor ordinal data (low < medium < high). Factors are essential becauselm()/aov()automatically create dummy variables from them. [keeps the class (a sub-list),[[extracts the element itself — the most common interview distinction.
Reading data, control flow and functions
- Input:
read.csv("file.csv"),read.table(..., header = TRUE, sep = "\t"),readxl::read_excel(),scan(); output:write.csv(),saveRDS()/readRDS(). - Conditionals:
if / else if / else; the vectorised form isifelse(cond, yes, no);switch()for multiway choice. - Loops:
for (i in 1:n) { },while,repeatwithbreak/next— correct but slow; prefer vectorisation. - apply family:
apply(m, 1, mean)(1 = rows, 2 = columns),lapply(returns list),sapply(simplifies to vector),vapply,mapply,tapply(y, group, mean)for group-wise summaries,Map/Reduce. - User function:
f <- function(x, k = 2) { x^k }— arguments can have defaults, matching is by name then position; the last evaluated expression is returned unlessreturn()is used. - Scoping: lexical. A function modifies a local copy, so
f(x)cannot changexoutside (no call-by-reference);<<-writes to the enclosing environment and is best avoided. - Debug and timing:
traceback(),browser(),debug(),system.time(),tryCatch()for error handling.
Descriptive statistics and graphics
- Univariate:
mean,median,var,sd,range,quantile,IQR,summary,fivenum;table()for frequencies,prop.table()for relative frequencies,cut()to form class intervals. - R's
var()andsd()use the divisor (n − 1); multiply by (n − 1)/n for the biased/population version. Skewness and kurtosis are not in base R — usemomentsore1071. - Bivariate:
cor(x, y)(Pearson;method = "spearman"or"kendall"),cov(),cor.test(). - Base graphics:
plot(),hist(),boxplot(),barplot(),pie(),stem(),qqnorm/qqline,curve(), withmain,xlab,col,pch,lty; add layers withpoints(),lines(),abline(),legend();par(mfrow = c(1,2))for panels. - ggplot2 (grammar of graphics):
ggplot(df, aes(x, y)) + geom_point() + facet_wrap(~grp) + labs(). - dplyr/tidyverse verbs:
filter,select,mutate,arrange,group_by+summarise, joined by the pipe%>%(or base|>) — the modern replacement for repeatedsubset/tapply.
Probability distributions and simulation
- Four prefixes on every distribution name: d = pmf/pdf, p = CDF (lower tail by default), q = quantile (inverse CDF), r = random numbers.
- Core names:
norm,binom,pois,unif,exp,t,chisq,f,geom,hyper,gamma,beta. - Examples:
dbinom(3, 10, 0.4),pnorm(1.96)≈ 0.975,qnorm(0.975)≈ 1.96,rnorm(100, mean = 50, sd = 5),qt(0.975, df = 24). - **
set.seed(123)** fixes the pseudo-random stream so results reproduce — compulsory in any simulation answer or practical record. sample(x, size, replace = TRUE/FALSE)for SRSWR/SRSWOR, lottery sampling and bootstrap resampling;replicate(1000, mean(sample(...)))builds a sampling distribution, which is how the CLT and the behaviour of estimators are demonstrated in practicals.- Monte Carlo use: estimating probabilities, integrals, bias and MSE of estimators, empirical power of a test.
Inference, regression and models
- Tests:
t.test()(one-sample, two-sample withvar.equal =, paired withpaired = TRUE),var.test()(F-test for two variances),chisq.test()(goodness of fit withp =, or independence on a matrix),prop.test(),binom.test(),shapiro.test()(normality),wilcox.test(),kruskal.test(),ks.test(). - Output to read: statistic,
df, p-value, confidence interval, estimate. Decide by p-value < α (usually 0.05), and state the conclusion in words. - ANOVA:
aov(y ~ group)thensummary(); two-way withy ~ A + Bory ~ A * B(interaction);TukeyHSD()for post-hoc comparison. The grouping variable must be a factor, else R fits a regression. - Regression:
fit <- lm(y ~ x1 + x2, data = df);summary(fit)gives coefficients, standard errors, t and p values, R², adjusted R² and the overall F-test;coef,fitted,resid,predict(fit, newdata),confint(fit),anova(fit),plot(fit)for the four diagnostic plots. - GLM:
glm(y ~ x, family = binomial)for logistic regression,family = poissonfor counts;AIC()for model comparison,step()for selection. - Other standard content: time series objects
ts(),acf(),arima()/forecast;prcomp()for PCA;kmeans();survival::survfit().
Why R, and how it compares
- Advantages: free under GPL; built by statisticians so new methods arrive on CRAN first; publication-quality graphics; vectorised syntax; strong reproducibility through R Markdown; excellent for surveys (
surveypackage handles weights and design effects for NSS-type data). - Limitations: data is held in RAM, so very large datasets need
data.table,arrowor a database; loops are slow (write C++ viaRcppif needed); single-threaded by default; error messages are terse; package quality varies. - R vs Python: R is stronger for classical inference, experimental design and statistical reporting; Python for production code, deep learning and engineering pipelines. Most Indian analytics teams use both.
- Validated/regulated work (clinical trials under the New Drugs and Clinical Trials Rules, 2019 and CDSCO submissions) traditionally uses SAS, but R with a validated environment is increasingly accepted; the exact acceptance rules differ by sponsor and should be checked case by case.
Key points
- Everything is an object — data, functions and models alike;
str()andclass()tell you what you are holding. - Vectorisation — operations apply element-wise to whole vectors; loops are a last resort.
- Recycling — a shorter vector repeats to match the longer one, silently if lengths are multiples.
- Indexing — 1-based; negative index deletes; logical index filters; names index by label.
- Vector vs list — a vector is one mode; a list can hold anything, including other lists and models.
- Data frame — rectangular list, one column per variable, the standard dataset format.
- Factor — categorical variable with levels; needed for correct ANOVA and dummy coding.
- **
[vs[[** —[returns the same class (subset),[[extracts the single element. - **
NAhandling** — usena.rm = TRUE, test withis.na(), never with== NA. - d/p/q/r prefixes — density, CDF, quantile, random generation for every distribution.
- **
set.seed()** — makes simulation output reproducible. - **
sd()/var()use n − 1** — the unbiased sample versions. - **
apply/sapply/tapply** — row/column summaries, list mapping, group-wise statistics. - **
t.test,chisq.test,aov,lm** — the four functions that cover most practical and viva questions. - **
summary(lm)** — read coefficients, p-values, R², adjusted R² and the F statistic. - Pipes —
%>%/|>chain dplyr verbs into a readable data-manipulation pipeline. - CRAN — the official repository;
install.packages()once,library()every session. - R Markdown — code, output and commentary in one reproducible document.
Formulas and examples
mean(x)Sample variance: s² = Σ(xᵢ − x̄)² / (n − 1); s = √s² — R:
var(x), sd(x)Coefficient of variation: CV = (s / x̄) × 100 % — R:
100*sd(x)/mean(x)One-sample t: t = (x̄ − μ₀) / (s/√n), df = n − 1 — R:
t.test(x, mu = mu0)Two-sample pooled t: t = (x̄₁ − x̄₂) / √(s_p²(1/n₁ + 1/n₂)), s_p² = ((n₁−1)s₁² + (n₂−1)s₂²)/(n₁+n₂−2), df = n₁+n₂−2
Chi-square: χ² = Σ (O − E)² / E; df = k − 1 (goodness of fit) or (r−1)(c−1) (independence)
Regression slope: b = Sxy / Sxx, intercept a = ȳ − b x̄, where Sxy = Σ(x−x̄)(y−ȳ), Sxx = Σ(x−x̄)²
Correlation: r = Sxy / √(Sxx · Syy); R² = r² for simple linear regression
ANOVA F = MSB / MSW = (SSB/(k−1)) / (SSW/(N−k))
Symbols: n = sample size, x̄ = mean, s = standard deviation, O/E = observed/expected frequency, k = number of classes or groups, N = total observations. Units are those of the data (₹, kg, marks); CV, R² and p-values are dimensionless.
Example 1 — descriptive statistics by hand and in R. Marks: 12, 15, 18, 20, 25.
- Σx = 90, n = 5 → x̄ = 90/5 = 18.
- Deviations: −6, −3, 0, 2, 7; squares 36, 9, 0, 4, 49 → Σ = 98.
- s² = 98/4 = 24.5; s = √24.5 = 4.9497; CV = 100 × 4.9497/18 = 27.5 %.
- Median = 18, range = 25 − 12 = 13.
x <- c(12, 15, 18, 20, 25)
mean(x); var(x); sd(x); median(x); summary(x)
100 * sd(x) / mean(x) # 27.49832
Example 2 — one-sample t-test on the same data, H₀: μ = 15 against H₁: μ ≠ 15, α = 0.05.
- SE = s/√n = 4.9497/√5 = 4.9497/2.2361 = 2.2136.
- t = (18 − 15)/2.2136 = 1.355, df = 4.
- Critical value
qt(0.975, 4)= 2.776. |t| = 1.355 < 2.776 → do not reject H₀ (p ≈ 0.247). - 95 % CI = 18 ± 2.776 × 2.2136 = 18 ± 6.147 = (11.85, 24.15), which contains 15 — the same conclusion.
t.test(x, mu = 15)
Example 3 — simple linear regression. x = 1,2,3,4,5; y = 2,4,5,4,5.
- x̄ = 3, ȳ = 20/5 = 4. x-deviations: −2,−1,0,1,2; y-deviations: −2,0,1,0,1.
- Sxy = 4 + 0 + 0 + 0 + 2 = 6; Sxx = 4+1+0+1+4 = 10; Syy = 4+0+1+0+1 = 6.
- b = 6/10 = 0.6; a = 4 − 0.6 × 3 = 2.2 → ŷ = 2.2 + 0.6x.
- r = 6/√(10 × 6) = 6/7.746 = 0.7746; R² = 36/60 = 0.60.
- SS_reg = b·Sxy = 3.6; SS_res = 6 − 3.6 = 2.4; MS_res = 2.4/3 = 0.8 → F = 3.6/0.8 = 4.5 with (1, 3) df;
qf(0.95,1,3)= 10.13, so the slope is not significant at 5 % (p ≈ 0.124). - Prediction at x = 6: ŷ = 2.2 + 3.6 = 5.8.
fit <- lm(y ~ x); summary(fit); predict(fit, data.frame(x = 6))
Example 4 — chi-square goodness of fit (fair die, 60 throws). Observed 8, 10, 12, 9, 11, 10; expected 60/6 = 10 each.
- (O−E)²: 4, 0, 4, 1, 1, 0 → Σ(O−E)²/E = 10/10 = χ² = 1.0, df = 5.
qchisq(0.95, 5)= 11.07 → 1.0 < 11.07, die is consistent with being fair (p ≈ 0.963).
chisq.test(c(8,10,12,9,11,10))
Example 5 — binomial probability and a check by simulation. n = 10, p = 0.3, find P(X ≤ 2).
- P(0) = 0.7¹⁰ = 0.028248; P(1) = 10(0.3)(0.7⁹) = 0.121061; P(2) = 45(0.3²)(0.7⁸) = 0.233474.
- Sum = 0.38278 →
pbinom(2, 10, 0.3)= 0.3827828.
set.seed(1)
mean(rbinom(1e6, 10, 0.3) <= 2) # ≈ 0.3828, matches the exact value
| Task | Base R | tidyverse |
|---|---|---|
| Read a CSV | read.csv() | readr::read_csv() |
| Keep rows | df[df$age > 30, ] | filter(df, age > 30) |
| New column | df$bmi <- w/h^2 | mutate(df, bmi = w/h^2) |
| Group means | tapply(y, g, mean) | group_by(g) %>% summarise(mean(y)) |
| Scatter plot | plot(x, y) | ggplot(df, aes(x,y)) + geom_point() |
Where it is used
- Pharma and clinical research: CROs and biostatistics teams in Hyderabad, Bengaluru and Ahmedabad use R for randomisation, sample-size, survival analysis and tables/listings/figures for regulatory submissions.
- Official statistics and public health: MoSPI/NSS and ICMR-type studies analyse survey data in R with design weights (
surveypackage); NFHS-style indicators and epidemiological modelling. - Banking, insurance and risk: credit scorecards (logistic regression), model validation and stress-test reporting at Indian banks and NBFCs; IRDAI-regulated insurers use R alongside actuarial tools for pricing and reserving.
- Market research and FMCG analytics: conjoint analysis, segmentation and media-mix models at Nielsen, Kantar and in-house analytics teams.
- Agriculture and quality: ICAR/IASRI design-of-experiments work (RBD, split-plot), and Six Sigma/SPC control charts (
qcc) in manufacturing. - Job roles: statistician, biostatistician, data analyst, research associate, quantitative analyst, academic research and teaching — R is also the tool of choice for M.Sc/Ph.D dissertations.
Interview questions
- Q: How does a list differ from a vector in R? A: A vector holds elements of one mode only; a list can hold objects of different types and lengths, including other lists, which is why model outputs are lists.
- Q: What is the difference between
[and[[? A:[returns a subset of the same class (for a list, a shorter list);[[extracts the single underlying element itself. - Q: What is the recycling rule? A: When vectors of unequal length are combined, the shorter one is repeated to match the longer; it warns only if the lengths are not exact multiples.
- Q: Why is a factor needed instead of a character vector? A: A factor stores the categories as coded levels, so modelling functions treat the variable as categorical and build dummy variables; it also controls the order of levels in tables and plots.
- Q: What do d, p, q and r mean in
dnorm,pnorm,qnorm,rnorm? A: Density, cumulative probability, quantile (inverse CDF) and random generation respectively. - Q: Why use
set.seed()? A: It fixes the pseudo-random number stream so the same simulated numbers and results are obtained on every run — essential for reproducible practicals and reports. - Q: Does
sd()divide by n or n − 1? A: By n − 1, the unbiased sample standard deviation; multiply by √((n−1)/n) for the population version. - Q: How do you handle missing values? A: Detect with
is.na(), usena.rm = TRUEin summaries,complete.cases()/na.omit()to drop rows, or impute; never compare with== NA. - Q: What does
summary()of anlmobject give? A: Residual quantiles, coefficient estimates with standard errors, t statistics and p-values, residual standard error, R² and adjusted R², and the overall F-test. - Q:
applyversussapplyversustapply? A:applyworks across rows/columns of a matrix,sapplyapplies a function to each element of a list/vector and simplifies the result,tapplycomputes a summary of one vector split by a factor. - Q: Why are loops discouraged in R? A: R is interpreted, so each iteration carries overhead; vectorised functions (
sum,+,colMeans) run compiled C code over the whole vector and are far faster. The apply family is itself a loop and is mainly shorter and clearer, not dramatically faster. - Q: When would you choose Python over R? A: For production pipelines, web/app integration, very large data and deep learning; R stays preferable for classical inference, design of experiments and statistical reporting.
Common mistakes
- Writing
=where<-is needed inside a function call, so an argument is set instead of an object created (mean(x = 1:5)versusx <- 1:5). - Treating R as 0-indexed, or thinking
x[-1]returns the last element (it deletes the first). - Forgetting
na.rm = TRUEand reportingNAas the answer, or filtering withx == NAinstead ofis.na(x). - Running
aov()/lm()with a numeric group code instead of a factor, which fits a regression on the codes and gives a wrong ANOVA table. - Confusing
pnormwithqnorm, or forgettinglower.tail = FALSEfor an upper-tail probability. - Reporting output without interpretation — an exam answer must state the hypotheses, the statistic, the p-value and the conclusion in words.
- Filling a matrix with
matrix(1:6, 2)and assuming row-wise order (it is column-wise unlessbyrow = TRUE), and omittingset.seed()so simulation results cannot be reproduced.
Related topics
Python for data analysis: NumPy and pandas · Testing of hypotheses · Regression and correlation analysis · Design of experiments and ANOVA · Sampling theory and survey methods · Probability distributions