R's real power comes from its package ecosystem. This page walks through the 50 libraries you will run into constantly, grouped by what they are for, with a plain-English explanation and a short example for each.
How to Use This Page
Every R package is installed once with install.packages("name") and loaded at the top of a script with library(name). You do not need to memorise all 50 of these - skim the category headings, and come back to this page as a reference whenever you hit a new package name in someone else's code.
install.packages("dplyr") # one-time install library(dplyr) # load it at the top of every script that uses it
1. Data Manipulation (Tidyverse Core)
These packages work with data frames and tibbles (a tidyverse-flavoured data frame) - the everyday job of cleaning, reshaping, and transforming a dataset before analysis.
#01dplyr
The single most-used data manipulation package in R - filter rows, select columns, create new columns, and summarise data using a small, consistent set of verbs.
- Works on: data frames / tibbles
- Core verbs: filter(), select(), mutate(), arrange(), summarise(), group_by()
- Chains operations together with the pipe %>% or |>
library(dplyr) students |> filter(score >= 80) |> group_by(class) |> summarise(avg = mean(score))
class | avg A | 90.0
#02tidyr
Reshapes data between wide and long formats - the package that untangles messy, spreadsheet-style data into one row per observation.
- Works on: data frames / tibbles
- Core functions: pivot_longer(), pivot_wider(), separate(), unite(), drop_na()
library(tidyr) wide_df |> pivot_longer(cols = Jan:Mar, names_to = "month", values_to = "sales")
#03tibble
A modern rework of the data frame - prints more nicely, never silently converts strings to factors, and never partial-matches column names.
- Works on: creates/represents rectangular data, drop-in replacement for data.frame
- Core functions: tibble(), as_tibble(), glimpse()
library(tibble) df <- tibble(name = c("Rafi","Meera"), score = c(88,92))
#04magrittr
Introduced the pipe operator (%>%) that made chained, readable data-manipulation code possible - largely superseded by base R's built-in |> pipe since R 4.1, but still everywhere in existing code.
- Works on: any object, purely a syntax tool
- Core operator: %>% ("then")
library(magrittr) students %>% filter(score > 80) %>% nrow()
#05purrr
Functional programming for R - applies a function to every element of a list or vector, replacing many for loops with one consistent set of tools.
- Works on: lists and vectors
- Core functions: map(), map_dbl(), map_chr(), pmap()
library(purrr) map_dbl(1:5, ~ .x^2)
[1] 1 4 9 16 25
#06readr
Fast, consistent reading and writing of rectangular text files (CSV, TSV) - the tidyverse's answer to base R's read.csv().
- Works on: reads/writes text files into a tibble
- Core functions: read_csv(), read_tsv(), write_csv()
library(readr) df <- read_csv("students.csv")
2. Import, Export & Databases
These packages move data in and out of R - from spreadsheets, other statistical software, web APIs, or a live database connection.
#07readxl
Reads Excel .xls/.xlsx files into a data frame - no external software (like Excel itself) required.
- Works on: reads Excel files into a tibble
- Core functions: read_excel(), excel_sheets()
library(readxl) df <- read_excel("data.xlsx", sheet = 1)
#08writexl
The write-side counterpart to readxl - exports a data frame to a real .xlsx file without needing Java or Excel installed.
- Works on: writes a data frame/tibble to Excel
- Core function: write_xlsx()
library(writexl) write_xlsx(df, "output.xlsx")
#09haven
Imports data files from other statistical software - SPSS (.sav), Stata (.dta), and SAS - preserving variable labels and value labels.
- Works on: reads foreign statistical formats into a tibble
- Core functions: read_sav(), read_dta(), read_sas()
library(haven) df <- read_sav("survey.sav")
#10jsonlite
Converts between R objects and JSON, the data format used by most web APIs.
- Works on: lists, data frames, and nested JSON structures
- Core functions: fromJSON(), toJSON()
library(jsonlite) data <- fromJSON("https://api.example.com/data")
#11DBI
A standard interface for connecting R to any relational database - the common language that database-specific packages (like RSQLite) plug into.
- Works on: SQL query results, returned as data frames
- Core functions: dbConnect(), dbGetQuery(), dbWriteTable()
library(DBI) con <- dbConnect(RSQLite::SQLite(), "mydb.sqlite") result <- dbGetQuery(con, "SELECT * FROM students")
#12RSQLite
The SQLite database driver for DBI - lets R read and write a real, file-based SQL database with zero server setup.
- Works on: local .sqlite database files
- Used together with: DBI
library(RSQLite) con <- DBI::dbConnect(SQLite(), ":memory:")
#13httr
Makes HTTP requests to web APIs - the standard way to pull live data from the internet directly into R.
- Works on: web API responses (often paired with jsonlite to parse them)
- Core functions: GET(), POST(), content()
library(httr) response <- GET("https://api.example.com/data") data <- httr::content(response, as = "parsed")
3. Data Visualization
Packages for turning data into charts, ranging from ggplot2's complete grammar-of-graphics system to small helper packages that polish an existing plot.
#14ggplot2
R's dominant charting package, covered in depth earlier in this guide - builds plots in layers using a consistent grammar (data, aesthetics, geometry, styling).
- Works on: data frames / tibbles
- Core functions: ggplot(), aes(), geom_*(), theme_*()
library(ggplot2) ggplot(df, aes(x, y)) + geom_point()
#15plotly
Creates interactive, zoomable, hoverable charts for HTML output - can convert an existing ggplot2 chart into an interactive one with a single function call.
- Works on: data frames, or wraps an existing ggplot object
- Core functions: plot_ly(), ggplotly()
library(plotly) p <- ggplot(df, aes(x, y)) + geom_point() ggplotly(p) # same chart, now interactive
#16lattice
An older, high-level plotting system built into base R's recommended packages - especially strong for 'trellis' charts that repeat the same plot across many subgroups.
- Works on: data frames
- Core functions: xyplot(), bwplot(), histogram()
library(lattice)
xyplot(score ~ study_hours | group, data = df)#17RColorBrewer
A curated set of colour palettes designed specifically for maps and statistical charts - sequential, diverging, and qualitative palettes that are colourblind-safe.
- Works on: returns colour hex codes to use in any plot
- Core function: brewer.pal()
library(RColorBrewer) colours <- brewer.pal(3, "Set2")
#18scales
Formats axis labels and legend breaks nicely - percentages, currency, comma-separated thousands - and provides the colour-scaling machinery ggplot2 uses internally.
- Works on: numeric vectors (as label formatters)
- Core functions: percent(), comma(), dollar()
library(scales) ggplot(df, aes(x, y)) + geom_col() + scale_y_continuous(labels = scales::percent)
#19gridExtra
Arranges multiple separate plots (including base R and ggplot2 plots) into a single grid layout.
- Works on: plot objects
- Core function: grid.arrange()
library(gridExtra) grid.arrange(plot1, plot2, ncol = 2)
#20patchwork
A more modern, ggplot2-native way to combine multiple plots - just add plot objects together with +, /, and | operators.
- Works on: ggplot2 plot objects
- Core syntax: p1 + p2, p1 / p2, p1 | p2
library(patchwork) p1 + p2 # side by side p1 / p2 # stacked
4. String & Date/Time Handling
Base R can handle text and dates, but these packages make both dramatically easier and more consistent to work with.
#21stringr
A consistent, easy-to-remember set of functions for working with text - every function starts with str_ and takes the string first.
- Works on: character vectors
- Core functions: str_detect(), str_replace(), str_split(), str_trim()
library(stringr) str_detect(c("apple","banana"), "an")
[1] FALSE TRUE
#22lubridate
Makes working with dates and times far less painful than base R - parsing, arithmetic, and extracting components (year, month, weekday) all become one-line calls.
- Works on: Date and POSIXct (date-time) vectors
- Core functions: ymd(), mdy(), today(), wday(), interval()
library(lubridate) d <- ymd("2026-07-17") wday(d, label = TRUE)
[1] Fri Levels: Sun < Mon < ... < Sat
#23glue
Interpolates variables directly into strings using {curly braces} - a cleaner alternative to paste0() for building formatted text and messages.
- Works on: any R values, embedded inside a string template
- Core function: glue()
library(glue) name <- "Rafi"; score <- 88 glue("{name} scored {score} points")
Rafi scored 88 points
5. Statistical Modelling
Beyond the base lm()/glm() functions used earlier in this guide, these packages extend R into more specialised statistical modelling.
#24stats
Loaded automatically in every R session - contains the core statistical functions used constantly: t.test(), lm(), glm(), aov(), and every common probability distribution.
- Works on: vectors and data frames
- Core functions: lm(), t.test(), aov(), dnorm()/pnorm()/qnorm()
# stats is always loaded automatically - no library() call needed t.test(score ~ group, data = df)
#25car
'Companion to Applied Regression' - adds regression diagnostics and tests that base R lacks, like tests for multicollinearity and non-constant variance.
- Works on: fitted model objects (from lm(), glm())
- Core functions: vif(), Anova(), ncvTest()
library(car) vif(model) # variance inflation factor - checks multicollinearity
#26lme4
Fits mixed-effects (multilevel/hierarchical) models - for data with a nested structure, like repeated measurements on the same patient or students within schools.
- Works on: data frames with a grouping/nesting structure
- Core functions: lmer(), glmer()
library(lme4) model <- lmer(score ~ study_hours + (1|school), data = df)
#27survival
The standard package for survival analysis - modelling time-to-event data, like time until patient relapse or equipment failure.
- Works on: Surv() objects built from time and event/status columns
- Core functions: Surv(), survfit(), coxph()
library(survival) fit <- survfit(Surv(time, status) ~ group, data = df)
#28MASS
'Modern Applied Statistics with S' - a broad toolkit bundled with base R, covering robust regression, LDA/QDA classification, and negative binomial models.
- Works on: data frames / fitted models
- Core functions: lda(), glm.nb(), stepAIC()
library(MASS) model <- MASS::glm.nb(count ~ x, data = df) # negative binomial regression
6. Machine Learning
Packages for building predictive models beyond classical statistics - from single algorithms to complete, unified ML workflows.
#29caret
'Classification And REgression Training' - a long-standing unified interface for training and comparing dozens of different ML models with consistent syntax.
- Works on: data frames
- Core functions: train(), trainControl(), predict()
library(caret) model <- train(class ~ ., data = df, method = "rf")
#30randomForest
Implements the Random Forest algorithm - an ensemble of decision trees, one of the most reliable general-purpose classification/regression methods.
- Works on: data frames (predictors + a target column)
- Core function: randomForest()
library(randomForest) model <- randomForest(class ~ ., data = df, ntree = 500)
#31xgboost
An extremely fast, high-performance implementation of gradient boosted trees - a top choice in machine learning competitions and production systems.
- Works on: numeric matrices (via xgb.DMatrix)
- Core functions: xgboost(), xgb.DMatrix(), predict()
library(xgboost) model <- xgboost(data = X_matrix, label = y, nrounds = 100)
#32glmnet
Fits regularised regression (Ridge, Lasso, and Elastic Net) - useful when you have many predictors and need automatic variable selection or shrinkage.
- Works on: numeric predictor matrix + outcome vector
- Core functions: glmnet(), cv.glmnet()
library(glmnet) model <- cv.glmnet(X_matrix, y, alpha = 1) # alpha=1 is Lasso
#33e1071
A grab-bag statistics/ML package best known for Support Vector Machines (SVM) and Naive Bayes classifiers, plus the skewness()/kurtosis() functions used earlier in this guide.
- Works on: data frames
- Core functions: svm(), naiveBayes(), skewness()
library(e1071)
model <- svm(class ~ ., data = df)#34tidymodels
A modern, tidyverse-style collection of packages for the ENTIRE modelling workflow - recipes for preprocessing, parsnip for model fitting, yardstick for evaluation.
- Works on: data frames / tibbles
- Core packages: recipes, parsnip, workflows, yardstick
library(tidymodels) model_spec <- linear_reg() |> set_engine("lm")
#35rpart
Fits a single classification or regression tree - simpler and more interpretable than a random forest, and often the first model tried on a new problem.
- Works on: data frames
- Core functions: rpart(), predict()
library(rpart) tree <- rpart(class ~ ., data = df, method = "class")
7. Reporting, Documents & Apps
Turns R code and results into shareable output - reports, slides, and fully interactive web applications, all without leaving R.
#36rmarkdown
Combines narrative text, R code, and its output into a single document, rendered to HTML, PDF, or Word - the standard way to produce reproducible reports directly from R.
- Works on: .Rmd source files (text + embedded R code chunks)
- Core function: render()
--- title: "My Report" output: html_document --- ```{r} summary(df) ```
#37knitr
The engine underneath rmarkdown that actually runs the embedded R code chunks and weaves the results back into the document.
- Works on: .Rmd/.Rnw source files
- Core function: knit()
library(knitr) knit("report.Rmd")
#38shiny
Builds fully interactive web applications using only R code - sliders, dropdowns, and live-updating plots, with no HTML/JavaScript required.
- Works on: reactive R expressions driving UI elements
- Core functions: fluidPage(), renderPlot(), shinyApp()
library(shiny) ui <- fluidPage(sliderInput("n", "N", 1, 100, 50), plotOutput("plot"))
#39flexdashboard
Turns an R Markdown document into a polished, grid-based dashboard layout with minimal extra syntax - often combined with shiny for interactivity.
- Works on: .Rmd files with a special dashboard layout syntax
- Core output format: flex_dashboard
--- title: "Dashboard" output: flexdashboard::flex_dashboard ---
8. Web Scraping
#40rvest
Extracts data directly from HTML web pages - selects elements with CSS selectors and pulls out text, links, or table data.
- Works on: parsed HTML documents
- Core functions: read_html(), html_elements(), html_table()
library(rvest) page <- read_html("https://example.com") titles <- page |> html_elements("h2") |> html_text()
9. Performance & Large Data
These packages exist to make R faster - either through a more efficient data structure, compiled C++ code, or running work across multiple CPU cores at once.
#41data.table
An extremely fast, memory-efficient alternative to data.frame for large datasets, with its own concise syntax (DT[i, j, by]).
- Works on: its own data.table object (extends data.frame)
- Core syntax: DT[rows, columns, by = grouping]
library(data.table) DT <- as.data.table(df) DT[score > 80, .(avg = mean(score)), by = class]
#42Rcpp
Lets you write small, performance-critical pieces of R code directly in C++ - used when a loop or calculation is too slow in pure R.
- Works on: compiles and calls C++ functions from R
- Core functions: cppFunction(), sourceCpp()
library(Rcpp) cppFunction("int add(int x, int y) { return x + y; }") add(2, 3)
[1] 5
#43parallel
Built into base R - runs independent computations across multiple CPU cores simultaneously, speeding up loops and simulations.
- Works on: any function applied repeatedly (like sapply/lapply)
- Core functions: mclapply(), makeCluster(), parLapply()
library(parallel) results <- mclapply(1:4, function(x) x^2, mc.cores = 4)
#44foreach
Provides a for-loop-like syntax that can run either sequentially or in parallel, depending on which 'backend' is registered.
- Works on: any iterable sequence
- Core syntax: foreach(...) %do% { ... } or %dopar% { ... }
library(foreach) foreach(i = 1:3) %do% { i^2 }
#45doParallel
A parallel 'backend' that plugs into foreach, letting %dopar% loops actually run across multiple cores instead of one at a time.
- Works on: registers a parallel cluster for foreach to use
- Core functions: registerDoParallel(), makeCluster()
library(doParallel) registerDoParallel(cores = 4) foreach::foreach(i = 1:3) %dopar% { i^2 }
10. Utility & Workflow
These packages do not analyse data directly - they support the process of writing, testing, organising, and cleaning up an R project.
#46devtools
A toolkit for building R packages - loading, testing, and documenting your own code as a reusable, shareable package.
- Works on: an R package project directory
- Core functions: load_all(), document(), install()
library(devtools) load_all() # reload your in-development package
#47testthat
R's standard unit-testing framework - write small checks that confirm your functions behave correctly, and catch bugs before they reach production.
- Works on: R functions, via test files
- Core functions: test_that(), expect_equal(), expect_true()
library(testthat) test_that("addition works", { expect_equal(2 + 2, 4) })
#48here
Solves the 'file not found' working-directory problem - builds file paths relative to your project's root, no matter where a script is run from.
- Works on: file paths
- Core function: here()
library(here) df <- read.csv(here("data", "students.csv"))
#49janitor
Cleans up messy real-world data - standardises column names, removes empty rows/columns, and builds clean summary tables.
- Works on: data frames
- Core functions: clean_names(), tabyl(), remove_empty()
library(janitor) df <- df |> clean_names() # "Student Name" -> "student_name"
#50forcats
Tools specifically for working with factors (categorical variables) - reordering, relabelling, and collapsing levels cleanly.
- Works on: factor vectors
- Core functions: fct_reorder(), fct_lump(), fct_recode()
library(forcats) df$class <- fct_relevel(df$class, "B", "A") # set custom level order
Key Points
- install.packages("name") installs a package once; library(name) loads it at the start of a script.
- install.packages("tidyverse") installs dplyr, tidyr, tibble, purrr, readr, stringr, ggplot2, and more together.
- Match the package to the job: dplyr/tidyr for wrangling, ggplot2 for charts, caret/tidymodels for machine learning, data.table for very large data.
- When code you find online fails with "could not find function", it almost always means the package providing that function has not been loaded with library() yet.