This chapter shows how to perform filter, select, and group-by operations using different data frame implementations:
base R’s data.frame
data.table’s data.table
dplyr’s tbl_df
polars’ RPolarsDataFrame
tidypolars
duckplyr
Base R and dplyr are both slow for large datasets. data.table is very fast and features a very concise and efficient syntax, but is limited to in-memory data. polars is very fast and can handle both in-memory and out-of-memory data, but features a possibly cumbersome syntax. tidypolars allows using dplyr syntax with polars data frames. DuckDB is also very fast and can handle both in-memory and out-of-memory data, but uses SQL syntax, not great for data frame operations. duckplyr uses dplyr syntax with DuckDB data frames.
Throughout this chapter, we will add head() as needed only in examples that would result in printing the entire data frame.
59.1 Setup
59.1.1 Load packages
Note the masking of functions that happens when all these packages are loaded together. In practice, you may want/have to stick to using a single approach at a time.
Following isntructions on the duckplyr docs, we will not load duckplyr directly, but rather use the duckplyr::as_duckplyr_df to convert the iris data frame to to a duckplyr data frame.
library(data.table)
Attaching package: 'data.table'
The following object is masked from 'package:base':
%notin%
library(dplyr)
Attaching package: 'dplyr'
The following objects are masked from 'package:data.table':
between, first, last
The following objects are masked from 'package:stats':
filter, lag
The following objects are masked from 'package:base':
intersect, setdiff, setequal, union
library(polars)library(tidypolars)
Error in `library()`:
! there is no package called 'tidypolars'
59.1.2 DuckDB
The following code enables reporting of fallbacks to dplyr when duckplyr fails.
Sys.setenv(DUCKPLYR_FALLBACK_VERBOSE =TRUE)
59.1.3 Create data frames
We will use the iris built-in dataset for this chapter and create a data.table, a tibble, a RPolarsDataFrame, and a duckplyr version of it.
The duckplyr package is configured to fall back to dplyr when it encounters an
incompatibility. Fallback events can be collected and uploaded for analysis to
guide future development. By default, data will be collected but no data will
be uploaded.
ℹ Automatic fallback uploading is not controlled and therefore disabled, see
`?duckplyr::fallback()`.
✔ Number of reports ready for upload: 10.
→ Review with `duckplyr::fallback_review()`, upload with
`duckplyr::fallback_upload()`.
ℹ Configure automatic uploading with `duckplyr::fallback_config()`.
Warning: `as_duckplyr_df()` was deprecated in duckplyr 1.0.0.
ℹ Please use `as_duckdb_tibble()` instead.
head(iris_db)
duckdb is storing downloaded extensions and secrets under ~/.duckdb:
ℹ /Users/sdg/.duckdb
This persists across sessions and is shared with the DuckDB CLI and other clients.
ℹ Run duckdb(shared_home = FALSE) to use a temporary directory instead.
ℹ See ?duckdb_storage for details and alternatives.
Error in `iris_pl$filter()`:
! Evaluation failed in `$filter()`.
Caused by error:
! Evaluation failed in `$collect()`.
Caused by error:
! Column(s) not found: "versicolor" not found
iris_pl |>filter( Sepal.Length <5.6, Species %in%c("versicolor", "virginica") )
Error in `UseMethod()`:
! no applicable method for 'filter' applied to an object of class "c('polars_data_frame', 'polars_object')"
iris_db |>filter( Sepal.Length <5.6, Species %in%c("versicolor", "virginica") )