dbMatrix objects support Arith and Ops operations. We will demonstrate how to perform arithmetic operations on dbSparseMatrix objects.
Note: Some operations with zero values are not yet supported with dbMatrix objects. In addition, certain arithmetic operations between dbMatrix objects are also not yet supported. We welcome user feedback and reporting issues on the Github page.
Let’s create a simple sparse matrix for demonstration:
# Create a sparse matrix
set.seed(42)
dgc <- Matrix::rsparsematrix(100, 50, density = 0.1, rand.x = function(n) rpois(n, 5) + 1)
rownames(dgc) <- paste0("gene_", seq_len(100))
colnames(dgc) <- paste0("cell_", seq_len(50))
dplyr::glimpse(dgc)
#> Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
#> ..@ i : int [1:500] 1 7 15 26 32 38 48 81 90 93 ...
#> ..@ p : int [1:51] 0 12 22 33 38 46 54 66 80 89 ...
#> ..@ Dim : int [1:2] 100 50
#> ..@ Dimnames:List of 2
#> .. ..$ : chr [1:100] "gene_1" "gene_2" "gene_3" "gene_4" ...
#> .. ..$ : chr [1:50] "cell_1" "cell_2" "cell_3" "cell_4" ...
#> ..@ x : num [1:500] 4 7 5 7 3 8 4 5 4 7 ...
#> ..@ factors : list()The matrix contains 100 rows (genes) and 50 columns (cells). Like most single-cell RNA-seq data, the matrix is sparse.
Let’s create a dbSparseMatrix object from the above dgc object.
# Note: by default the constructor creates a dbMatrix object in-memory
con <- DBI::dbConnect(duckdb::duckdb(), ":memory:")
dbsm <- dbMatrix(
value = dgc,
con = con,
name = "test_matrix",
class = "dbSparseMatrix",
overwrite = TRUE
)
# preview the object
dbsm
#> 100 x 50 dbMatrix of class "dbSparseMatrix"
#> [[ Colnames 'cell_1', 'cell_2', 'cell_3' ... suppressing 44 ...'cell_48', 'cell_49', 'cell_50' ]]
#>
#> gene_1 . . . . . . 5.0000000 .
#> gene_2 4.0000000 . . . . . . .
#> gene_3 . 7.0000000 . . . 8.0000000 . 3.0000000
#>
#> ......suppressing 40 columns and 94 rows
#>
#> gene_98 . . . . . . . .
#> gene_99 . . 5.0000000 . . . . .
#> gene_100 7.0000000 . . . . . . .dbMatrix emulates scalar arithmetic in the Matrix package.
Note: Addition or subtraction with non-zero addends on a dbSparseMatrix results in a dbDenseMatrix.
dbsm + 1
#> ℹ Performing on-the-fly densification (cold path). See ?dbMatrix_options for details.
#> 100 x 50 dbMatrix of class "dbDenseMatrix"
#> [[ Colnames 'cell_1', 'cell_2', 'cell_3' ... suppressing 44 ...'cell_48', 'cell_49', 'cell_50' ]]
#>
#> gene_1 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 6.0000000
#> gene_2 5.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000
#> gene_3 1.0000000 8.0000000 1.0000000 1.0000000 1.0000000 9.0000000 1.0000000
#>
#> ......suppressing 40 columns and 94 rows
#>
#> gene_98 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000
#> gene_99 1.0000000 1.0000000 6.0000000 1.0000000 1.0000000 1.0000000 1.0000000
#> gene_100 8.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000
dbsm * 100
#> 100 x 50 dbMatrix of class "dbSparseMatrix"
#> [[ Colnames 'cell_1', 'cell_2', 'cell_3' ... suppressing 44 ...'cell_48', 'cell_49', 'cell_50' ]]
#>
#> gene_1 . . . . . . 500.0000000
#> gene_2 400.0000000 . . . . . .
#> gene_3 . 700.0000000 . . . 800.0000000 .
#>
#> ......suppressing 40 columns and 94 rows
#>
#> gene_98 . . . . . . .
#> gene_99 . . 500.0000000 . . . .
#> gene_100 700.0000000 . . . . . .dbMatrix also supports matrix arithmetic for dbMatrix objects that are conformable.
dbsm + dbsm
#> 100 x 50 dbMatrix of class "dbSparseMatrix"
#> [[ Colnames 'cell_1', 'cell_2', 'cell_3' ... suppressing 44 ...'cell_48', 'cell_49', 'cell_50' ]]
#>
#> gene_1 . . . . . . 10.0000000 .
#> gene_2 8.0000000 . . . . . . .
#> gene_3 . 14.0000000 . . . 16.0000000 . 6.0000000
#>
#> ......suppressing 40 columns and 94 rows
#>
#> gene_98 . . . . . . . .
#> gene_99 . . 10.0000000 . . . . .
#> gene_100 14.0000000 . . . . . . .dbsm * dbsm
#> 100 x 50 dbMatrix of class "dbSparseMatrix"
#> [[ Colnames 'cell_1', 'cell_2', 'cell_3' ... suppressing 44 ...'cell_48', 'cell_49', 'cell_50' ]]
#>
#> gene_1 . . . . . . 25.0000000 .
#> gene_2 16.0000000 . . . . . . .
#> gene_3 . 49.0000000 . . . 64.0000000 . 9.0000000
#>
#> ......suppressing 40 columns and 94 rows
#>
#> gene_98 . . . . . . . .
#> gene_99 . . 25.0000000 . . . . .
#> gene_100 49.0000000 . . . . . . .TODO
sessionInfo()
#> R version 4.5.2 (2025-10-31)
#> Platform: x86_64-pc-linux-gnu
#> Running under: AlmaLinux 8.10 (Cerulean Leopard)
#>
#> Matrix products: default
#> BLAS/LAPACK: FlexiBLAS NETLIB; LAPACK version 3.12.0
#>
#> locale:
#> [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
#> [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
#> [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
#> [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
#> [9] LC_ADDRESS=C LC_TELEPHONE=C
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
#>
#> time zone: America/New_York
#> tzcode source: system (glibc)
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] dbMatrix_0.1.0
#>
#> loaded via a namespace (and not attached):
#> [1] bit_4.6.0 Matrix_1.7-4 jsonlite_2.0.0
#> [4] dplyr_1.1.4 compiler_4.5.2 tidyselect_1.2.1
#> [7] Rcpp_1.1.0 blob_1.2.4 nanoarrow_0.7.0-1
#> [10] pins_1.4.1 assertthat_0.2.1 dbProject_0.0.0.9002
#> [13] jquerylib_0.1.4 arrow_22.0.0 yaml_2.3.10
#> [16] fastmap_1.2.0 lattice_0.22-7 R6_2.6.1
#> [19] generics_0.1.4 knitr_1.50 tibble_3.3.0
#> [22] MatrixGenerics_1.22.0 DBI_1.2.3 bslib_0.9.0
#> [25] pillar_1.11.1 connections_0.2.1 rlang_1.1.6
#> [28] cachem_1.1.0 xfun_0.54 sass_0.4.10
#> [31] bit64_4.6.0-1 cli_3.6.5 withr_3.0.2
#> [34] magrittr_2.0.4 digest_0.6.38 grid_4.5.2
#> [37] rscontract_0.1.2 dbplyr_2.5.1 lifecycle_1.0.4
#> [40] vctrs_0.6.5 evaluate_1.0.5 glue_1.8.0
#> [43] data.table_1.17.8 duckdb_1.4.2 rmarkdown_2.30
#> [46] purrr_1.2.0 matrixStats_1.5.0 tools_4.5.2
#> [49] pkgconfig_2.0.3 htmltools_0.5.8.1