What's New in R 4.5
R 4.5.0, nicknamed “How About a Twenty-Six,” arrived on April 11th, 2025. This release focuses on improving the everyday experience of R programmers—from how you load packages to how you install them.
This article covers the changes that matter most for practical R programming.
The penguins Dataset
If you have ever learned R for data science, you have probably worked with the iris dataset. It is classic but showing its age—the measurements come from just three species of iris flowers, collected in the 1930s.
R 4.5 introduces the Palmer Penguins dataset as a base dataset:
# Load the penguins dataset (new in R 4.5)
data(penguins)
head(penguins)
# species island bill_len_mm bill_dep_mm flipper_len_mm body_mass_g sex
# 1 Adelie Torgersen 39.1 18.7 181 3750 MALE
# 2 Adelie Torgersen 39.5 17.4 186 3800 FEMALE
# 3 Adelie Torgersen 40.3 18.0 195 3250 FEMALE
# 4 Adelie Torgersen NA NA NA NA <NA>
# 5 Adelie Torgersen 36.7 19.3 183 3450 FEMALE
# 6 Adelie Torgersen 39.3 18.9 190 3650 MALE
There is also a penguins_raw version with the original, unreduced data—useful for teaching data cleaning workflows.
This dataset includes measurements from 344 penguins across three species (Adelie, Chinstrap, and Gentoo) from three islands in the Palmer Archipelago. It is a better choice than iris for demonstrating classification and clustering because it has more variation and a cleaner story behind the data.
The use() Function
Loading packages in R has always been all-or-nothing. You either use dplyr::filter() to call a function without loading the package, or you run library(dplyr) and get every exported function in your namespace. The latter causes problems when packages have conflicting function names.
R 4.5 introduces use() as a middle ground:
# Only import specific functions from dplyr
use("dplyr", c("filter", "select"))
# Now filter() and select() are available
penguins |>
filter(species == "Adelie") |>
select(species:bill_dep_mm)
# But other dplyr functions are not loaded
n_distinct(penguins$species)
# Error: could not find function "n_distinct"
This is similar to what the {box} and {import} packages have offered, but now it is in base R. You get precise control over what enters your namespace, which reduces bugs from unexpected function masking.
The trade-off is that you need to know exactly which functions you want upfront. For quick exploratory work, library() is still convenient. For production code or functions that will be used by others, use() gives you more confidence about what is available.
Parallel Package Downloads
If you have ever installed many packages at once, you know it can be slow. Historically, install.packages() downloaded and installed packages one at a time.
R 4.5 changes this:
# In R 4.5, packages download in parallel (2-5x faster)
install.packages(c("dplyr", "tidyr", "ggplot2", "purrr", "readr"))
The speedup varies depending on your network and the packages, but typical improvements are 2-5x. This makes setting up a new R environment noticeably faster.
This works automatically—you do not need to change any code. The underlying logic handles dependency resolution correctly even when downloading in parallel.
The grepv() Function
Pattern matching in base R uses grep(), which returns indices by default:
comments <- c("Nest never observed", "Some other text", "Nest building")
grep("Nest", comments)
# [1] 1 3
To get the matching values instead, you needed value = TRUE:
grep("Nest", comments, value = TRUE)
# [1] "Nest never observed" "Nest building"
R 4.5 adds grepv() as a convenience function that does this automatically:
# grepv returns values directly
grepv("Nest", comments)
# [1] "Nest never observed" "Nest building"
It is a small quality-of-life improvement, but if you use pattern matching frequently, it makes your code slightly cleaner.
C23 Compiler Support
R 4.5 prefers the C23 standard when compiling packages from source. If you have a C23-capable compiler installed, R will use it. This affects package developers more than everyday users.
Most users will not notice this change. It matters if you compile packages from source and want access to the latest C language features.
What You Should Do
If you are upgrading to R 4.5:
-
Try the penguins dataset — If you teach R or write tutorials, consider switching from iris to penguins. It is more interesting and has a better story.
-
Experiment with use() — For functions that will be used in production or by others, try
use()instead oflibrary(). It gives you cleaner namespaces. -
Enjoy faster package installs — The parallel downloads happen automatically. You do not need to change anything, but the speed improvement is noticeable when setting up new environments.
-
Use grepv() when you need values — It is a minor convenience, but code becomes slightly more readable when you want matched strings rather than indices.
The use() function is the biggest change for everyday coding. It addresses a long-standing complaint about R’s package loading model without requiring external packages.