# iscream compatible data structures

#### 18 May 2026

The examples here show how iscream output can be converted into other data structures for further analysis.

    library(iscream)

    ## iscream using 1 thread by default but parallelly::availableCores() detects 4 possibly available threads. See `?set_threads` for information on multithreading before trying to use more.
    ## 'tabix' executable not found in $PATH. tabix() will use htslib to make queries instead which can be slower. See ?tabix for details.
    ## NOTE: 'htslib' was not compiled with libdeflate which supports fast querying. See <https://huishenlab.github.io/iscream/articles/htslib.html> for more information

    data_dir <- system.file("extdata", package = "iscream")
    bedfiles <- list.files(data_dir, pattern = "[a|b|c|d].bed.gz$", full.names = TRUE)
    regions <- c(A = "chr1:1-6", B = "chr1:7-10", C = "chr1:11-14")

## 1 GenomicRanges

    if (!require("GenomicRanges", quietly = TRUE)) {
      stop("The 'GenomicRanges' package must be installed for this functionality")
    }

`GRanges` objects can be used as the input regions to all of iscream’s functions and can be returned by `tabix_gr()` and `make_mat_gr()`.

### 1.1 From `tabix` queries

`tabix_gr()` returns a `GenomicRanges` object. The `regions` parameter can be a string vector, a data frame or a `GRanges` object. If given a `GRanges` object with metadata, those columns will be preserved in the output.

    gr <- GRanges(regions)
    values(gr) <- DataFrame(
        gene = c("gene1", "gene2", "gene3"),
        some_metadata = c("s1", "s2", "s3")
    )
    gr

    ## GRanges object with 3 ranges and 2 metadata columns:
    ##     seqnames    ranges strand |        gene some_metadata
    ##        <Rle> <IRanges>  <Rle> | <character>   <character>
    ##   A     chr1       1-6      * |       gene1            s1
    ##   B     chr1      7-10      * |       gene2            s2
    ##   C     chr1     11-14      * |       gene3            s3
    ##   -------
    ##   seqinfo: 1 sequence from an unspecified genome; no seqlengths

    tabix_gr(bedfiles[1], gr)

    ## GRanges object with 7 ranges and 4 metadata columns:
    ##       seqnames    ranges strand |        V1        V2        gene some_metadata
    ##          <Rle> <IRanges>  <Rle> | <numeric> <integer> <character>   <character>
    ##   [1]     chr1       1-2      * |       1.0         1       gene1            s1
    ##   [2]     chr1       3-4      * |       1.0         1       gene1            s1
    ##   [3]     chr1       5-6      * |       0.0         2       gene1            s1
    ##   [4]     chr1       7-8      * |       0.0         1       gene2            s2
    ##   [5]     chr1      9-10      * |       0.5         2       gene2            s2
    ##   [6]     chr1     11-12      * |       1.0         2       gene3            s3
    ##   [7]     chr1     13-14      * |       1.0         3       gene3            s3
    ##   -------
    ##   seqinfo: 1 sequence from an unspecified genome; no seqlengths

The `data.table` output of `tabix()` can also be piped into `GRanges`, but does not preserve input metadata.

    tabix(bedfiles[1], gr) |>
      makeGRangesFromDataFrame(
        starts.in.df.are.0based = TRUE,
        keep.extra.columns = TRUE
      )

    ## GRanges object with 7 ranges and 2 metadata columns:
    ##       seqnames    ranges strand |        V1        V2
    ##          <Rle> <IRanges>  <Rle> | <numeric> <integer>
    ##   [1]     chr1       1-2      * |       1.0         1
    ##   [2]     chr1       3-4      * |       1.0         1
    ##   [3]     chr1       5-6      * |       0.0         2
    ##   [4]     chr1       7-8      * |       0.0         1
    ##   [5]     chr1      9-10      * |       0.5         2
    ##   [6]     chr1     11-12      * |       1.0         2
    ##   [7]     chr1     13-14      * |       1.0         3
    ##   -------
    ##   seqinfo: 1 sequence from an unspecified genome; no seqlengths

If the input BED file is not zero-based (e.g. Bismark coverage files), set `zero_based = FALSE` in the `tabix()` call to get the correct conversion from data frame to GenomicRanges.

### 1.2 From `summarize_regions()`

`summarize_regions()` returns a data frame with the input `regions` positions and summaries of the BED-file data columns.

    (summary <- summarize_regions(
      bedfiles,
      regions,
      column = 4,
      col_names = ("data_col"),
      fun = c("sum", "mean"))
    )

    ## [18:28:10.503328] [iscream::summarize_regions] [info] Summarizing 3 regions from 4 bedfiles
    ## [18:28:10.503705] [iscream::summarize_regions] [info] using sum, mean
    ## [18:28:10.503718] [iscream::summarize_regions] [info] with columns 4 as data_col

    ##        chr start   end   file feature data_col.sum data_col.mean
    ##     <char> <int> <int> <char>  <char>        <num>         <num>
    ##  1:   chr1     1     6      a       A          2.0     0.6666667
    ##  2:   chr1     7    10      a       B          0.5     0.2500000
    ##  3:   chr1    11    14      a       C          2.0     1.0000000
    ##  4:   chr1     1     6      b       A          1.0     0.5000000
    ##  5:   chr1     7    10      b       B          1.0     1.0000000
    ##  6:   chr1    11    14      b       C          1.0     0.5000000
    ##  7:   chr1     1     6      c       A          1.0     1.0000000
    ##  8:   chr1     7    10      c       B          1.0     0.5000000
    ##  9:   chr1    11    14      c       C           NA            NA
    ## 10:   chr1     1     6      d       A          2.0     1.0000000
    ## 11:   chr1     7    10      d       B          0.5     0.2500000
    ## 12:   chr1    11    14      d       C          1.0     1.0000000

    GRanges(summary)

    ## GRanges object with 12 ranges and 4 metadata columns:
    ##        seqnames    ranges strand |        file     feature data_col.sum
    ##           <Rle> <IRanges>  <Rle> | <character> <character>    <numeric>
    ##    [1]     chr1       1-6      * |           a           A          2.0
    ##    [2]     chr1      7-10      * |           a           B          0.5
    ##    [3]     chr1     11-14      * |           a           C          2.0
    ##    [4]     chr1       1-6      * |           b           A          1.0
    ##    [5]     chr1      7-10      * |           b           B          1.0
    ##    ...      ...       ...    ... .         ...         ...          ...
    ##    [8]     chr1      7-10      * |           c           B          1.0
    ##    [9]     chr1     11-14      * |           c           C           NA
    ##   [10]     chr1       1-6      * |           d           A          2.0
    ##   [11]     chr1      7-10      * |           d           B          0.5
    ##   [12]     chr1     11-14      * |           d           C          1.0
    ##        data_col.mean
    ##            <numeric>
    ##    [1]      0.666667
    ##    [2]      0.250000
    ##    [3]      1.000000
    ##    [4]      0.500000
    ##    [5]      1.000000
    ##    ...           ...
    ##    [8]          0.50
    ##    [9]            NA
    ##   [10]          1.00
    ##   [11]          0.25
    ##   [12]          1.00
    ##   -------
    ##   seqinfo: 1 sequence from an unspecified genome; no seqlengths

### 1.3 From `make_mat`

`make_mat_gr()` returns a `GRanges` object for dense matrices.

    make_mat_gr(bedfiles, regions, column = 4, mat_name = "beta")

    ## [18:28:10.556685] [iscream::query_all] [info] Querying 3 regions from 4 bedfiles
    ##
    ## [18:28:10.557142] [iscream::query_all] [info] Creating metadata vectors
    ## [18:28:10.557152] [iscream::query_all] [info] 7 loci found - 9993 extra rows allocated with 0 resizes
    ## [18:28:10.557157] [iscream::query_all] [info] Creating dense matrix

    ## GRanges object with 7 ranges and 4 metadata columns:
    ##       seqnames    ranges strand |         a         b         c         d
    ##          <Rle> <IRanges>  <Rle> | <numeric> <numeric> <numeric> <numeric>
    ##   [1]     chr1         0      * |       1.0         0         0       1.0
    ##   [2]     chr1         2      * |       1.0         0         1       1.0
    ##   [3]     chr1         4      * |       0.0         1         0       0.0
    ##   [4]     chr1         6      * |       0.0         1         0       0.0
    ##   [5]     chr1         8      * |       0.5         0         1       0.5
    ##   [6]     chr1        10      * |       1.0         0         0       0.0
    ##   [7]     chr1        12      * |       1.0         1         0       1.0
    ##   -------
    ##   seqinfo: 1 sequence from an unspecified genome; no seqlengths

## 2 SummarizedExperiment

`make_mat_se()` returns a `RangedSummarizedExperiment` for both sparse and dense matrices.

    if (!require("SummarizedExperiment", quietly = TRUE)) {
      stop("The 'SummarizedExperiment' package must be installed for this functionality")
    }
    make_mat_se(bedfiles, regions, column = 4, mat_name = "beta", sparse = TRUE)

    ## [18:28:11.893582] [iscream::query_all] [info] Querying 3 regions from 4 bedfiles
    ##
    ## [18:28:11.894220] [iscream::query_all] [info] Creating metadata vectors
    ## [18:28:11.894229] [iscream::query_all] [info] 7 loci found - 9993 extra rows allocated with 0 resizes
    ## [18:28:11.894236] [iscream::query_all] [info] Creating sparse matrix

    ## class: RangedSummarizedExperiment
    ## dim: 7 4
    ## metadata(0):
    ## assays(1): beta
    ## rownames: NULL
    ## rowData names(0):
    ## colnames(4): a b c d
    ## colData names(0):

### 2.1 Making `BSseq` objects

A bsseq object is a type of SummarizedExperiment, but it cannot handle sparse matrices:

    if (!require("bsseq", quietly = TRUE)) {
      stop("The 'bsseq' package must be installed for this functionality")
    }
    mats <- make_mat_bsseq(bedfiles, regions, sparse = FALSE)

    ## [18:28:14.229011] [iscream::query_all] [info] Querying 3 regions from 4 bedfiles
    ##
    ## [18:28:14.229761] [iscream::query_all] [info] Creating metadata vectors
    ## [18:28:14.229777] [iscream::query_all] [info] 7 loci found - 9993 extra rows allocated with 0 resizes
    ## [18:28:14.229782] [iscream::query_all] [info] Creating dense matrix

    do.call(BSseq, mats)

    ## An object of type 'BSseq' with
    ##   7 methylation loci
    ##   4 samples
    ## has not been smoothed
    ## All assays are in-memory

## 3 Session info

    sessionInfo()

    ## R version 4.6.0 Patched (2026-05-01 r89994)
    ## Platform: aarch64-apple-darwin23
    ## Running under: macOS Tahoe 26.3.1
    ##
    ## Matrix products: default
    ## BLAS:   /Library/Frameworks/R.framework/Versions/4.6/Resources/lib/libRblas.0.dylib
    ## LAPACK: /Library/Frameworks/R.framework/Versions/4.6/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.1
    ##
    ## locale:
    ## [1] C/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
    ##
    ## time zone: America/New_York
    ## tzcode source: internal
    ##
    ## attached base packages:
    ## [1] stats4    stats     graphics  grDevices utils     datasets  methods
    ## [8] base
    ##
    ## other attached packages:
    ##  [1] bsseq_1.49.0                SummarizedExperiment_1.43.0
    ##  [3] Biobase_2.73.1              MatrixGenerics_1.25.0
    ##  [5] matrixStats_1.5.0           GenomicRanges_1.65.0
    ##  [7] Seqinfo_1.3.0               IRanges_2.47.1
    ##  [9] S4Vectors_0.51.2            BiocGenerics_0.59.2
    ## [11] generics_0.1.4              iscream_1.3.0
    ## [13] BiocStyle_2.41.0
    ##
    ## loaded via a namespace (and not attached):
    ##  [1] farver_2.1.2              R.utils_2.13.0
    ##  [3] Biostrings_2.81.1         bitops_1.0-9
    ##  [5] fastmap_1.2.0             RCurl_1.98-1.18
    ##  [7] GenomicAlignments_1.49.0  stringfish_0.19.0
    ##  [9] XML_3.99-0.23             digest_0.6.39
    ## [11] lifecycle_1.0.5           statmod_1.5.2
    ## [13] compiler_4.6.0            rlang_1.2.0
    ## [15] sass_0.4.10               tools_4.6.0
    ## [17] yaml_2.3.12               data.table_1.18.4
    ## [19] rtracklayer_1.73.0        knitr_1.51
    ## [21] S4Arrays_1.13.0           curl_7.1.0
    ## [23] DelayedArray_0.39.2       RColorBrewer_1.1-3
    ## [25] abind_1.4-8               BiocParallel_1.47.0
    ## [27] HDF5Array_1.41.0          R.oo_1.27.1
    ## [29] grid_4.6.0                beachmat_2.29.0
    ## [31] Rhdf5lib_2.1.0            scales_1.4.0
    ## [33] gtools_3.9.5              dichromat_2.0-0.1
    ## [35] cli_3.6.6                 rmarkdown_2.31
    ## [37] crayon_1.5.3              otel_0.2.0
    ## [39] RcppParallel_5.1.11-2     httr_1.4.8
    ## [41] rjson_0.2.23              DelayedMatrixStats_1.35.0
    ## [43] BiocBaseUtils_1.15.1      pbapply_1.7-4
    ## [45] cachem_1.1.0              rhdf5_2.57.0
    ## [47] parallel_4.6.0            BiocManager_1.30.27
    ## [49] XVector_0.53.0            restfulr_0.0.16
    ## [51] Matrix_1.7-5              jsonlite_2.0.0
    ## [53] bookdown_0.46             h5mread_1.5.0
    ## [55] locfit_1.5-9.12           limma_3.69.0
    ## [57] jquerylib_0.1.4           glue_1.8.1
    ## [59] parallelly_1.47.0         codetools_0.2-20
    ## [61] BiocIO_1.23.3             htmltools_0.5.9
    ## [63] rhdf5filters_1.25.0       BSgenome_1.81.0
    ## [65] R6_2.6.1                  sparseMatrixStats_1.25.0
    ## [67] evaluate_1.0.5            lattice_0.22-9
    ## [69] R.methodsS3_1.8.2         Rsamtools_2.29.0
    ## [71] cigarillo_1.3.0           bslib_0.11.0
    ## [73] Rcpp_1.1.1-1.1            SparseArray_1.13.2
    ## [75] permute_0.9-10            xfun_0.57