We’re delighted to announce the release of pak 0.6.0. pak helps with the installation of R packages and many related tasks.
You can install pak from CRAN with:
install.packages("pak")
If you use an older R version, or a platform that CRAN does not have binary packages for, it is faster and simpler to install pak from our repository. See the details in the manual.
This blog post focuses on the exciting new improvements in the matching and installation of system requirements on Linux systems.
You can see a full list of changes in the release notes
System requirements
Many R packages require the installation of external software, otherwise they do not work, or even load. For example, the RPostgres R package requires the PostgreSQL client library, and by default dynamically links to it on Linux systems. This means that you (or the administrators of your system) need to install this library, typically in the form of a system package: libpq-dev
on Ubuntu and Debian systems, or postgresql-server-devel
or postgresql-devel
on Red Hat, Fedora, etc. systems.
The good news is that pak now helps you with this:
- it looks up the required system packages when installing R packages,
- it lets you know if any required system packages are missing from your system, before the installation, and
- it installs them automatically, if you are a superuser, or if you can use password-less
sudo
to start a superuser shell.
In addition, pak now also has some functions to query system requirements and system packages.
Supported platforms
pak 0.6.0 supports the following Linux systems currently:
- Ubuntu Linux,
- Debian Linux,
- Red Hat Enterprise Linux,
- SUSE Linux Enterprise,
- OpenSUSE,
- CentOS,
- Rocky Linux,
- Fedora Linux.
Call
pak::sysreqs_platforms()
to query the current list of supported platforms:
pak::sysreqs_platforms()[,1:3]
#> name os distribution
#> 1 Ubuntu Linux linux ubuntu
#> 2 Debian Linux linux debian
#> 3 CentOS Linux linux centos
#> 4 Rocky Linux linux rockylinux
#> 5 Red Hat Enterprise Linux linux redhat
#> 6 Red Hat Enterprise Linux linux redhat
#> 7 Red Hat Enterprise Linux linux redhat
#> 8 Fedora Linux linux fedora
#> 9 openSUSE Linux linux opensuse
#> 10 SUSE Linux Enterprise linux sle
Call
pak::system_r_platform()
to check if pak has detected your platform correctly, and
pak::sysreqs_is_supported()
to see if it is supported:
pak::system_r_platform()
#> [1] "x86_64-pc-linux-gnu-ubuntu-22.04"
pak::sysreqs_is_supported()
#> [1] TRUE
R package installation
If you are using pak as the root
user, on a supported platform, then during package installation pak will look up the required system packages, and will install the missing ones. Here is an example:
pak::pkg_install("RPostgres")
#> i Loading metadata databasev Loading metadata database ... done
#>
#> > Will install 12 packages.
#> > Will download 12 packages with unknown size.
#> + DBI 1.1.3 [dl]
#> + RPostgres 1.4.5 [dl] + x libpq-dev
#> + Rcpp 1.0.11 [dl]
#> + bit 4.0.5 [dl]
#> + bit64 4.0.5 [dl]
#> + blob 1.2.4 [dl]
#> + generics 0.1.3 [dl]
#> + hms 1.1.3 [dl]
#> + lubridate 1.9.2 [dl]
#> + pkgconfig 2.0.3 [dl]
#> + timechange 0.2.0 [dl]
#> + withr 2.5.0 [dl]
#> > Will install 1 system package:
#> + libpq-dev - RPostgres
#> i Getting 12 pkgs with unknown sizes
#> v Got blob 1.2.4 (x86_64-pc-linux-gnu-ubuntu-22.04) (45.94 kB)
#> v Got generics 0.1.3 (x86_64-pc-linux-gnu-ubuntu-22.04) (76.24 kB)
#> v Got hms 1.1.3 (x86_64-pc-linux-gnu-ubuntu-22.04) (98.35 kB)
#> v Got RPostgres 1.4.5 (x86_64-pc-linux-gnu-ubuntu-22.04) (455.11 kB)
#> v Got bit64 4.0.5 (x86_64-pc-linux-gnu-ubuntu-22.04) (475.41 kB)
#> v Got pkgconfig 2.0.3 (x86_64-pc-linux-gnu-ubuntu-22.04) (17.58 kB)
#> v Got timechange 0.2.0 (x86_64-pc-linux-gnu-ubuntu-22.04) (169.26 kB)
#> v Got DBI 1.1.3 (x86_64-pc-linux-gnu-ubuntu-22.04) (759.31 kB)
#> v Got withr 2.5.0 (x86_64-pc-linux-gnu-ubuntu-22.04) (228.73 kB)
#> v Got bit 4.0.5 (x86_64-pc-linux-gnu-ubuntu-22.04) (1.13 MB)
#> v Got lubridate 1.9.2 (x86_64-pc-linux-gnu-ubuntu-22.04) (980.37 kB)
#> v Got Rcpp 1.0.11 (x86_64-pc-linux-gnu-ubuntu-22.04) (2.15 MB)
#> i Installing system requirements
#> i Executing `sh -c apt-get -y update`
#> i Executing `sh -c apt-get -y install libpq-dev`
#> v Installed DBI 1.1.3 (1.1s)
#> v Installed RPostgres 1.4.5 (1.1s)
#> v Installed Rcpp 1.0.11 (1.2s)
#> v Installed bit 4.0.5 (1.2s)
#> v Installed bit64 4.0.5 (126ms)
#> v Installed blob 1.2.4 (86ms)
#> v Installed generics 0.1.3 (83ms)
#> v Installed hms 1.1.3 (59ms)
#> v Installed lubridate 1.9.2 (1.1s)
#> v Installed pkgconfig 2.0.3 (1.1s)
#> v Installed timechange 0.2.0 (63ms)
#> v Installed withr 2.5.0 (1.1s)
#> v 1 pkg + 16 deps: kept 5, added 12, dld 12 (6.58 MB) [17.1s]
Running R as a regular user
If you don’t want to use R as the superuser, but you can set up sudo
without a password, that works as well. pak will detect the password-less sudo
capability, and use it to install system packages, as needed.
If you run R as a regular (not root) user, and password-less sudo
is not available, then pak will print the system requirements, but it will not try to install or update them.
If you are compiling R packages from source, and they need to link to system libraries, then their installation will probably fail, until you install these system packages.
If you are installing binary R packages (e.g. from P3M), then the installation typically succeeds, but you won’t be able to load these packages into R, until you install the required system packages.
To demonstrate this, let’s remove the system package for the PostgreSQL client library:
system("apt-get remove -y libpq5")
If now we (re)install the binary RPostgres R package, the installation will succeed, but then
library()
fails because of the missing system package. (We will fix the broken R package below.)
#> i Loading metadata databasev Loading metadata database ... done
#>
#> > Will install 1 package.
#> > Will download 1 package with unknown size.
#> + RPostgres 1.4.5 [dl] + x libpq-dev
#> x Missing 1 system package. You'll probably need to install it manually:
#> + libpq-dev - RPostgres
#> i Getting 1 pkg with unknown size
#> v Cached copy of RPostgres 1.4.5 (x86_64-pc-linux-gnu-ubuntu-22.04) is the latest build
#> v Installed RPostgres 1.4.5 (1.1s)
#> v 1 pkg + 16 deps: kept 16, added 1 [5.7s]
library(RPostgres)
#> Error: package or namespace load failed for 'RPostgres' in dyn.load(file, DLLpath = DLLpath, ...):
#> unable to load shared object '/root/R/x86_64-pc-linux-gnu-library/4.3/RPostgres/libs/RPostgres.so':
#> libpq.so.5: cannot open shared object file: No such file or directory
#> Execution halted
Opting out
If you don’t want pak to install system packages for you, set the PKG_SYSREQS
environment variable to false
, or the pkg.sysreqs
option to FALSE
. See the complete list of configuration options in the
config?pak
manual page.
System requirements queries
pak 0.6.0 also has a number of functions to query system requirements and system packages. The
pak::pkg_sysreqs()
function is similar to
pak::pkg_deps()
but in addition to looking up package dependencies, it also looks up system dependencies, and only reports the latter:
pak::pkg_sysreqs(c("curl", "r-lib/xml2", "devtools", "CHRONOS"))
#> i Loading metadata databasev Loading metadata database ... done
#> -- Install scripts --------------------------------------------- Ubuntu 22.04 --
#> apt-get -y update
#> apt-get -y install libcurl4-openssl-dev libssl-dev git make libgit2-dev \
#> zlib1g-dev pandoc libfreetype6-dev libjpeg-dev libpng-dev libtiff-dev \
#> libicu-dev libfontconfig1-dev libfribidi-dev libharfbuzz-dev libxml2-dev \
#> libglpk-dev libgmp3-dev default-jdk
#> R CMD javareconf
#> R CMD javareconf
#>
#> -- Packages and their system dependencies --------------------------------------
#> CHRONOS -- default-jdk, pandoc
#> credentials -- git
#> curl -- libcurl4-openssl-dev, libssl-dev
#> fs -- make
#> gert -- libgit2-dev
#> gitcreds -- git
#> httpuv -- make, zlib1g-dev
#> igraph -- libglpk-dev, libgmp3-dev, libxml2-dev
#> knitr -- pandoc
#> openssl -- libssl-dev
#> pkgdown -- pandoc
#> png -- libpng-dev
#> ragg -- libfreetype6-dev, libjpeg-dev, libpng-dev, libtiff-dev
#> RCurl -- libcurl4-openssl-dev, make
#> remotes -- git
#> rJava -- default-jdk, make
#> rmarkdown -- pandoc
#> sass -- make
#> stringi -- libicu-dev
#> systemfonts -- libfontconfig1-dev, libfreetype6-dev
#> textshaping -- libfreetype6-dev, libfribidi-dev, libharfbuzz-dev
#> XML -- libxml2-dev
#> xml2 -- libxml2-dev
See the manual of
pak::pkg_sysreqs()
to learn how to programmatically extract information from its return value.
pak::sysreqs_check_installed()
is a handy function that checks if all system requirements are installed for some or all R packages in your library. This should report our broken RPostgres package:
pak::sysreqs_check_installed()
#> system package installed required by
#> -------------- -- -----------
#> libpq-dev x RPostgres
pak::sysreqs_fix_installed()
goes one step further and also tries to install the missing system requirements:
pak::sysreqs_fix_installed()
#> i Need to install 1 system package.
#> i Installing system requirements
#> i Executing `sh -c apt-get -y update`
#> i Executing `sh -c apt-get -y install libpq-dev`
Now we can load RPostgres again:
Configuration
There are several pak configuration options you can use to adjust how system requirements are handled. See the complete list in the
config?pak
manual page.
Other related pak functions
-
pak::sysreqs_db_list()
,pak::sysreqs_dbmatch()
andpak::sysreqs_db_update()
list, query and update the built-in system requirements database. -
pak::sysreqs_list_system_packages()
lists system packages, including virtual packages and the features they provide.
More information
Acknowledgements
A big thank you to all those who have contributed to pak, or one of its workhorse packages since the v0.5.1 release:
@alexpate30, @averissimo, @ArnaudKunzi, @billdenney, @Darxor, @drmowinckels, @Fan-iX, @gongyh, @hadley, @idavydov, @jefferis, @joan-yanqiong, @kevinushey, @kkmann, @klmr, @krlmlr, @lgaborini, @maelle, @maxheld83, @maximsmol, @michaelmayer2, @mine-cetinkaya-rundel, @olivroy, @pascalgulikers, @pawelru, @royfrancis, @tanho63, @thomasyu888, @vincent-hanlon, and @VincentGuyader.