## ----setup, include=FALSE-----------------------------------------------------
knitr::opts_chunk$set(collapse = TRUE, comment = "#>",
                      error = FALSE, warning = FALSE, message = FALSE)

## ----install, eval=FALSE------------------------------------------------------
# if (!require("BiocManager"))
#     install.packages("BiocManager")
# BiocManager::install("DuckDBArray")

## ----load---------------------------------------------------------------------
library(DuckDBArray)

## ----quickstart-data----------------------------------------------------------
library(arrow)

counts_df <- expand.grid(gene = paste0("Gene", 1:100),
                         cell = paste0("Cell", 1:20),
                         stringsAsFactors = FALSE)
set.seed(1L)
counts_df$count <- rpois(nrow(counts_df), lambda = 3)

parquet_path <- tempfile(fileext = ".parquet")
write_parquet(counts_df, parquet_path)

## ----quickstart-construct-----------------------------------------------------
mat <- DuckDBMatrix(parquet_path,
                    datacol = "count",
                    keycols = list(gene = paste0("Gene", 1:100),
                                   cell = paste0("Cell", 1:20)))
mat

## ----quickstart-ops-----------------------------------------------------------
dim(mat)
rowSums(mat)[1:5]
colMeans(mat)[1:5]

## ----write-matrix-------------------------------------------------------------
library(Matrix)

m <- Matrix(rpois(200 * 50, lambda = 1), nrow = 200, ncol = 50, sparse = TRUE)
rownames(m) <- paste0("Gene", seq_len(nrow(m)))
colnames(m) <- paste0("Cell", seq_len(ncol(m)))

path <- tempfile()
writeCoordArray(m, path)
dimtbls <- createDimTables(m)

mat2 <- DuckDBMatrix(path, datacol = "value",
                     keycols = list(index1 = setNames(seq_len(nrow(m)), rownames(m)),
                                    index2 = setNames(seq_len(ncol(m)), colnames(m))),
                     dimtbls = dimtbls)
dim(mat2)

## ----subset-------------------------------------------------------------------
sub <- mat[1:5, 1:4]
sub
as.matrix(sub)

## ----matrixstats--------------------------------------------------------------
library(MatrixGenerics)
rowSums(mat)[1:5]
rowVars(mat)[1:5]
colSds(mat)[1:5]

## ----feature-selection--------------------------------------------------------
rowNnzs(mat)[1:5]
rowDeviances(mat, family = "binomial")[1:5]

## ----sparse-------------------------------------------------------------------
is_sparse(mat2)
as(mat2[1:5, 1:4], "dgCMatrix")

## ----lazy---------------------------------------------------------------------
transformed <- log1p(mat) * 2
class(transformed)
as.matrix(transformed[1:3, 1:3])

## ----block-stream-------------------------------------------------------------
# one block in memory at a time; each block is a separate, pruned query
block_sums <- blockApply(mat, function(block) sum(block))
sum(unlist(block_sums))

## ----nd-array-----------------------------------------------------------------
arr_df <- expand.grid(i = 1:4, j = 1:3, k = 1:2)
arr_df$value <- rpois(nrow(arr_df), lambda = 2)
arr_path <- tempfile(fileext = ".parquet")
write_parquet(arr_df, arr_path)

arr <- DuckDBArray(arr_path, datacol = "value",
                   keycols = list(i = 1:4, j = 1:3, k = 1:2))
dim(arr)
arr[1:2, 1:2, 1]

## ----introspect-schema--------------------------------------------------------
open_dataset(arr_path)$schema

## ----introspect-keycols-------------------------------------------------------
scanKeycols(arr_path, keycols = c("i", "j", "k"))

## ----introspect-construct-----------------------------------------------------
arr2 <- DuckDBArray(arr_path, datacol = "value",
                    keycols = scanKeycols(arr_path, c("i", "j", "k")))
dim(arr2)

## ----sessioninfo--------------------------------------------------------------
sessionInfo()

