xcode-select --installInstalling R Packages on macOS That Require Compilation
1 Preparation
In order to compile R packages from source, you need to have the following tools installed on your system:
- Xcode Command Line Tools: These include the compilers and build tools needed to compile R packages from source. Run the following command in your terminal to install them. The command will prompt you to install the tools or report that they are already installed. If you already have Xcode and its command line tools installed, you can skip this step.
- Homebrew: This is a package manager for macOS that makes it easy to install and manage software packages. If you don’t have Homebrew installed, you can install it by running the following command in your terminal. You can also check the official Homebrew installation guide for more details.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"2 data.table
Sometimes, macOS upgrades can update the default compiler (clang) included with Xcode Command Line Tools, which might lead to compilation issues for certain R packages like data.table. For example, a recent issue arose with the macOS Sequoia beta where the updated clang version caused compilation failures (see Rdatatable/data.table#6622).
If you encounter such compilation problems after a macOS update, a potential workaround is to install an older version of the compiler using Homebrew, such as LLVM 16:
brew install llvm@16You can then set the CC and CXX environment variables to point to the older compiler version before installing the package:
export CC=/usr/local/opt/llvm@16/bin/clang
export CXX=/usr/local/opt/llvm@16/bin/clang++
2.1 Introduction to data.table
data.table is a high-performance extension of R’s data.frame that provides a syntax for data manipulation that is concise, consistent, and efficient. It’s particularly optimized for large datasets and offers significant performance improvements over base R and tidyverse’s dplyr.
2.2 Why data.table is superior to dplyr
Speed:
data.tableis consistently faster thandplyr, especially for large datasets, due to its C implementation and sophisticated optimization techniques.Memory efficiency:
data.tableoperations are typically performed in-place, which reduces memory overhead compared todplyr’s copy-on-modify approach.Concise syntax: Complex operations can be expressed in a single line of code using
data.table’s[i, j, by]syntax, which is more compact thandplyr’s pipe-based approach.Advanced features:
data.tableoffers powerful features like rolling joins, non-equi joins, and specialized grouped operations that aren’t as easily accessible indplyr.
2.3 Installation notes
If you install the data.table package directly from CRAN, it will be installed as a binary package. This means that the package is precompiled and does not require compilation on your machine. However, this may not always provide the best performance. The biggest disadvantage of using the binary version is that it usually does not use OpenMP on macOS and Linux. OpenMP is a parallel programming model that can significantly speed up computations, so without it, you lose the benefit of using multiple CPU cores.
To install the data.table package from source, follow these steps:
Preparation: Follow the preparation steps above in Section 1 to install Xcode Command Line Tools and Homebrew.
Install OpenMP: Install the
libomppackage using Homebrew, which provides support for OpenMP:
brew install libomp-
Customize Makevars: Create or edit the
~/.R/Makevarsfile to include the following lines:
# ~/.R/Makevars
CPPFLAGS += -Xclang -fopenmp
LDFLAGS += -lomp- CPPFLAGS: This variable is used to specify additional flags for the C++ compiler. The
-Xclang -fopenmpflag tells the compiler to enable OpenMP support. - LDFLAGS: This variable is used to specify additional flags for the linker. The
-lompflag tells the linker to link against the OpenMP library. - If you don’t have the
~/.R/Makevarsfile, you can create it using the following command:
mkdir -p ~/.R && touch ~/.R/Makevars-
Install data.table: After the above steps are done, you can install the
data.tablepackage from source using the following command in R:
install.packages("data.table", type = "source")3 qs2
3.1 Introduction to qs2
qs2 is a package for fast serialization and deserialization of R objects. It is particularly useful for saving and loading large datasets quickly, making it a great choice for data-intensive applications.
I previously used the fst package for serialization and deserialization, but I found qs2 more flexible because fst can save only data frames, whereas qs2 can save any R object.
3.2 Installation notes
To install the qs2 package from source, follow these steps:
- Preparation: Follow the preparation steps above in Section 1 to install Xcode Command Line Tools and Homebrew.
-
Install TBB: Install the
tbbpackage using Homebrew, which provides support for parallel programming using Intel’s Threading Building Blocks (TBB). TBB is required for theqs2package to enable parallel serialization and deserialization.
brew install tbb-
Add TBB environment variables: Add the following lines to your
~/.zshrcfile to set the TBB environment variables. This step is necessary for theqs2package to find the TBB library during installation. You can find the path by runningbrew --prefix tbb. Replace/usr/local/opt/tbbwith the actual path to the TBB installation on your system.
export TBB="/usr/local/opt/tbb"
export TBB_INC="$TBB/include"
export TBB_LIB="$TBB/lib"-
Install qs2: After the above steps are done, you can install the
qs2package from source using the following command in R. The official guide is here.
install.packages("qs2", type = "source", configure.args = "--with-TBB --with-simd=AVX2")-
--with-TBB: This flag tells theqs2package to use the TBB library for parallel serialization and deserialization. -
--with-simd=AVX2: This flag tells theqs2package to use AVX2 SIMD (Single Instruction, Multiple Data) instructions for further performance optimization. AVX2 is a set of CPU instructions that can perform multiple operations in parallel, which can significantly speed up computations.