Open-source project
fastverse/collapse avatar
fastverse/collapse

collapse: C-speed aggregation and statistics for R, without changing your data class

Advanced and Fast Data Transformation in R

709 stars37 forksCNOASSERTION

At a glance

What is it?
collapse is a C and C++ package for R that replaces the split-and-loop patterns used for grouped and weighted statistics with compiled routines, and it does so while accepting the data structures you already use, from data.table and tibble to xts and sf. The claim is speed; the real design decision is dispatching across classes instead of asking you to adopt a new one.
Who is it for?
collapse earns a place in an R workflow that aggregates, weights or reshapes large frames in a loop, especially when the data already lives in data.table, tibble or xts and you do not want to convert it first. It is the wrong choice if your work is a single small aggregation, or if you cannot install a compiled package, since the CRAN archive and GitHub routes both build from source.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The target is the aggregation loop, not the data frame

The package description is one line, advanced and fast data transformation in R, and the README explains what that means in practice. collapse is a large C and C++ based package for data transformation and statistical computing in R, and it states two aims: making complex data transformation, exploration and computing tasks easier, and making R code fast, parsimonious and programmer friendly.

The problem it targets is specific. R is good at holding a data frame, and slow at iterating over its groups in a loop. The idiomatic base R answer to a grouped statistic is to split the frame and apply a function to each piece, which allocates an intermediate list, re-does the grouping work and calls back into interpreted code thousands of times. collapse moves those operations into compiled code, and the README attributes the speed to its algorithms plus what it calls extremely low evaluation overheads, meaning the per call cost of its own functions is kept small.

The audience is therefore R users doing statistical work on real sized data: econometrics, panel data analysis, survey style weighting, time series. Someone running a single summary on a small data frame will gain nothing here and will pay the cost of a compiled dependency.

The claim is the package's own, and the README links benchmark pages for Linux and Windows rather than presenting numbers in the text, so a reader wanting proof has to go and look.

Class-agnostic dispatch is the architectural bet

The phrase the README uses for the design is a class-agnostic architecture, and the supporting list tells you what it means in practice. collapse supports all basic R objects and their popular extensions, including units, integer64, xts, zoo, tibble, grouped_df, data.table, sf, pseries and pdata.frame.

This is the part that separates collapse from the usual R performance story. The common approach is to say that a fast implementation needs its own data structure, and then to ask the user to migrate. collapse instead dispatches on whatever object it is handed, so a grouped computation can run over a data.table and over a plain data.frame through the same call. For a pipeline that already mixes a tibble in the middle of a data.table workflow, that removes a class of conversion bugs and a class of copies.

The trade off is that a class-agnostic layer has to know something about every class it accepts, and the support list is therefore the contract. The README names the supported extensions but does not enumerate the operations each one allows, so a function that behaves one way on a data.frame may have a narrower path on a grouped_df or a pseries. The documentation is where that is settled, and the package points at a dedicated article on object handling for the details.

Another consequence follows from the C and C++ core. The package ships compiled code, so installation is not a plain copy of a pure R library, and a source build needs a working toolchain on the machine.

Four install routes, and only two of them avoid a compiler

The installation section offers the current CRAN version first, which is the route to take unless you need something newer.

r
install.packages("collapse")

A stable development version with Windows and Mac binaries comes from the R-universe repository run by the same organisation, and this is the route to use when you want the newest code without a compiler on your side.

r
install.packages("collapse", repos = "https://fastverse.r-universe.dev")

The GitHub route installs the development version directly and, as the README notes, requires compilation.

r
remotes::install_github("fastverse/collapse")

The fourth route is the archive, for when you need to reproduce an analysis with the version that was current at the time. The README shows the tarball for 2.0.19 installed from source, and lists older stable versions down to 1.2.1.

r
install.packages("https://cran.r-project.org/src/contrib/Archive/collapse/collapse_2.0.19.tar.gz", 
                 repos = NULL, type = "source") 

Two operational points follow. First, pinning an archived version means compiling it, so reproducibility and a toolchain come as a pair. Second, the binary route through R-universe is limited to Windows and Mac, and a Linux user working from a development version is compiling regardless.

The package badges state a minimum R version of 3.5.0, and the archive install does not change that floor, so an old R installation cannot be rescued by choosing an old package version.

Grouped and weighted computation is where the value concentrates

The feature list is long, but it clusters around a few areas, and the first one is statistical programming on vectors, matrices and data frames, with grouped and weighted computations. The README also lists fast and programmable grouping, ordering, matching, deduplication, factor generation and interactions, which is the vocabulary of building the grouped structure in the first place rather than only summarising it.

Weighted statistics are the second concentration point, and they run through the package: weighted and multi-level descriptive statistics, weighted aggregation, weighted scaling, and weighted averaging. The package topics carry a weights tag, which is a fair signal of what a lot of users are there for, since weighted means and weighted quantiles in base R usually mean a loop.

The third area is aggregation, described as fast and easy multi-type, weighted and parallelized data aggregation. Parallelised here means the grouping and aggregation work can use multiple cores, which is the single biggest difference from a split and apply pipeline for a frame with many groups.

The fourth is transformation by reference: row and column arithmetic, sweeping out of statistics group by group, and scaling and centering, including the higher-dimensional versions. Working by reference is what avoids the copy that a base R implementation would make on every intermediate step.

List processing is the fifth, with recursive list search, filtering, splitting, apply and unlisting to a data frame, which is the part that turns the package from a statistics add-on into something you can build a data reshaping pipeline on.

Time series and panels get dedicated classes, not a workaround

The time computation section is the one that most often decides whether a package is usable in an economics or finance workflow. collapse provides indexed time series and panel data classes, lags and leads, differences and compound growth rates, and all of it on irregular time series as well as regular ones. It adds panel autocorrelation functions and conversions from panel data to arrays.

The irregular case is the one that matters. Base R time series operations assume evenly spaced observations, so a monthly panel with gaps has to be reindexed or handled by hand. Making that a supported case rather than an afterthought is a design decision that shows up directly in the amount of code you write.

Panel data is a first class citizen too, with pdata.frame and pseries among the classes the architecture supports, and the panel-autocorrelation and panel-to-array functions operating on that structure. For a user who already works in panel data, the question is not whether the package supports panels but whether the pdata.frame and pseries route gives the same results as their current code, which the documentation is where to check.

The functional list also names sweep out of statistics by reference and higher-dimensional centering and averaging, operations that are usually written once as a nested loop and then copied into every project.

The documentation is a help page, vignettes, a cheat sheet and a journal paper

A package of this size lives or dies on its documentation, and collapse takes that seriously. It installs with a built-in structured documentation implemented as a set of separate help pages, and calling help('collapse-documentation') opens a top-level page that gives an overview of the package and links to all the others. That is a deliberate choice over a single enormous help file, and it is the first thing a new user should open.

There are also vignettes, including one on documentation and resources, and a cheat sheet distributed as a PDF in the repository, which is the fastest way to find the function that does the operation you are trying to describe in base R.

For academic use, the README points at the article published in the Journal of Statistical Software, volume 116 issue 1, with a DOI, and calls it the primary reference and a concise introduction to the design and the capabilities. The same document exists as a citation file in the repository. Two conference presentations are also linked, one at useR 2022 and one at a workshop in 2025, with recordings and slides.

That combination tells you something about how the project is run. A journal article is a frozen snapshot, so the vignettes and the cheatsheet in the repository are the parts that move with the code, and they are the ones to read for current behaviour.

What the speed claim does not cover, and what a source build really costs

Two limits are worth stating plainly. The first is that the speed claim is about relative work, and the README frames it against base R and against the effort of writing the operation yourself. It is not a claim about every workload. A transformation that touches a handful of rows, or a pipeline whose bottleneck is reading files or calling a model, will not move. The benchmark links in the README are the place to see which operations were compared, and they point at external benchmark projects rather than publishing figures in the text, so the evidence lives somewhere else.

The second limit is installation. A compiled package needs a toolchain, and two of the four documented routes compile from source, including every archived version. On a locked-down machine without a compiler, the CRAN binary and the R-universe binary are the only workable options, which pins you to a released version.

There is a third, quieter limit. A class-agnostic layer has to make choices about how each class behaves, and where a class has no fast path the operation can only be as fast as the fallback. The supported extension list is long, but the README does not promise identical performance or identical semantics for every one of them.

What the README does not describe is any fallback behaviour for unsupported classes, any performance guidance by operation, or a comparison table between the grouped routines and the base R equivalents. Those are the questions to put to the package's own documentation and vignettes.

A 2.x version line, a custom licence classification and a young release history

The release history is regular. Version 2.1.8 was published on 2026-08-30, 2.1.7 on 2026-05-19 and 2.1.6 on 2025-12-22, and the repository is not archived with the last push on 2026-10-16. A package that reaches CRAN, is published on Conda, carries a CRAN check badge and a codecov coverage badge, and is archived on CRAN for every previous version is one that takes release engineering seriously, and the numbered line means the 2.1 series is the stable target.

The licence needs care. The repository ships a LICENSE file, and the source is credited to the fastverse organisation, but GitHub classifies the licence as a custom one that it cannot categorise. That usually means the licence text is not in a form its detector recognises, and it means you should read the file rather than trust the label shown on the repository page. This is a reading of the file layout, not legal advice.

One more thing changes the arithmetic for an organisation. The package is on CRAN, which means the canonical build for most users is a binary, and that binary is compiled for the R version you are running. If you need a specific older version, the archive route compiles it, and if you need reproducibility across machines, the tarball in the archive is the artefact to keep, not the version number.

Judged as a dependency, collapse sits in a good position: a published package with a version line, an archive of past builds, a documented installation path for both binaries and source, and a licence file you can read before shipping.

Editorial conclusion

collapse earns a place in an R workflow that aggregates, weights or reshapes large frames in a loop, especially when the data already lives in data.table, tibble or xts and you do not want to convert it first. It is the wrong choice if your work is a single small aggregation, or if you cannot install a compiled package, since the CRAN archive and GitHub routes both build from source. Verify two things before adopting it: that your R version satisfies the 3.5.0 minimum stated in the package badges, and that the class-agnostic dispatch behaves as you expect on the extension classes your pipeline actually uses, because the support list names units, integer64, xts, zoo, tibble, grouped_df, data.table, sf, pseries and pdata.frame, and that list is the contract.

Frequently asked questions

How do I install collapse for R?

The current CRAN version installs with install.packages("collapse"). A development version with Windows and Mac binaries comes from the R-universe repository, and the GitHub route installs from source and therefore requires compilation.

Which data classes does collapse support?

The package describes a class-agnostic architecture covering all basic R objects and popular extensions, naming units, integer64, xts, zoo, tibble, grouped_df, data.table, sf, pseries and pdata.frame. The package provides a dedicated article on object handling for the details of each.

Does collapse support weighted and grouped statistics?

Yes. The feature list includes grouped and weighted computations on vectors, matrices and data frames, multi-type weighted and parallelized aggregation, weighted scaling and weighted averaging, and grouped, multi-level descriptive statistics.

Can I install an older version of collapse from CRAN?

Yes, from the CRAN archive. The README shows a source install of the 2.0.19 tarball and lists older stable versions down to 1.2.1. Archived versions are installed from source, so they need a compiler.

What is the minimum R version for collapse?

The package badges state R 3.5.0 or newer as the minimum. That floor applies to the package itself, so choosing an older archived version does not lower it.

Official sources

  1. fastverse/collapse on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/fastverse-collapse.svg)](https://hysenlabs.com/projects/fastverse-collapse)

Was this useful?