## ----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("DuckDBGRanges")

## ----load---------------------------------------------------------------------
library(DuckDBGRanges)
library(GenomicRanges)

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

gr <- GRanges(
    seqnames = rep(c("chr1", "chr2"), c(3, 2)),
    ranges = IRanges(start = c(100, 200, 300, 150, 250),
                     end   = c(150, 275, 360, 230, 295)),
    strand  = c("+", "-", "+", "-", "+"),
    gene_id = paste0("GENE", 1:5),
    score   = c(10, 20, 15, 25, 18))

gr_df <- as.data.frame(gr)
gr_df$range_id <- paste0("range", seq_len(nrow(gr_df)))
gr_path <- tempfile(fileext = ".parquet")
write_parquet(gr_df, gr_path)

## ----quickstart-construct-----------------------------------------------------
gr_ddb <- DuckDBGRanges(gr_path,
                        seqnames = "seqnames", start = "start",
                        end = "end", strand = "strand",
                        keycol = list(range_id = gr_df$range_id),
                        mcols = c("gene_id", "score"))
gr_ddb

## ----quickstart-ops-----------------------------------------------------------
length(gr_ddb)
seqnames(gr_ddb)

## ----accessors----------------------------------------------------------------
start(gr_ddb)
width(gr_ddb)
ranges(gr_ddb)
gr_ddb$gene_id

## ----subset-------------------------------------------------------------------
gr_ddb[1:3]
gr_ddb[seqnames(gr_ddb) == "chr1"]
gr_ddb[gr_ddb$score > 15]
gr_ddb[gr_ddb %over% GRanges("chr1:150-250")]

## ----range-ops----------------------------------------------------------------
shift(gr_ddb, 50L)
restrict(gr_ddb, start = 200L, end = 300L)
reduce(gr_ddb)

## ----hybrid-------------------------------------------------------------------
## lazy, on-disk filter down to a manageable subset...
sub <- gr_ddb[seqnames(gr_ddb) == "chr1" & gr_ddb$score > 12]

## ...then materialize the small result for overlap work
sub_gr <- as(sub, "GRanges")
class(sub_gr)
findOverlaps(sub_gr, GRanges("chr1:100-320"))

## ----grangeslist--------------------------------------------------------------
grl_data <- data.frame(
    transcript_id = c("ENST001", "ENST002"),
    gene_id = c("GENE1", "GENE2"),
    seqnames = I(list(rep("chr1", 3), rep("chr2", 2))),
    start  = I(list(c(100L, 200L, 300L), c(150L, 250L))),
    width  = I(list(c(50L, 75L, 60L),   c(80L, 45L))),
    strand = I(list(c("+", "-", "+"),   c("-", "+"))))
grl_path <- tempfile(fileext = ".parquet")
write_parquet(grl_data, grl_path)

grl_ddb <- DuckDBGRangesList(grl_path,
                             seqnames = "seqnames", start = "start",
                             width = "width", strand = "strand",
                             mcols = "gene_id",
                             keycol = list(transcript_id = grl_data$transcript_id))
elementNROWS(grl_ddb)
grl_ddb[[1]]

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

