RleArray objects
RleArray-class.RdThe RleArray class is a DelayedArray subclass for representing an in-memory Run Length Encoded array-like dataset.
All the operations available for DelayedArray objects work on RleArray objects.
Arguments
- data
An Rle object, or an ordinary list of Rle objects, or an RleList object, or a DataFrame object where all the columns are Rle objects. More generally speaking,
datacan be any list-like object where all the list elements are Rle objects.- dim
The dimensions of the object to be created, that is, an integer vector of length one or more giving the maximal indices in each dimension.
- dimnames
The dimnames of the object to be created. Must be
NULLor a list of length the number of dimensions. Each list element must be eitherNULLor a character vector along the corresponding dimension.- chunksize
Experimental. Don't use!
See also
Rle and DataFrame objects in the S4Vectors package and RleList objects in the IRanges package.
DelayedArray objects.
DelayedArray-utils for common operations on DelayedArray objects.
realizefor realizing a DelayedArray object in memory or on disk.ConstantArray objects for mimicking an array containing a constant value, without actually creating said array in memory.
HDF5Array objects in the HDF5Array package.
The RleArraySeed helper class.
Examples
## ---------------------------------------------------------------------
## A. BASIC EXAMPLE
## ---------------------------------------------------------------------
data <- Rle(sample(6L, 500000, replace=TRUE), 8)
a <- array(data, dim=c(50, 20, 4000)) # array() expands the Rle object
# internally with as.vector()
A <- RleArray(data, dim=c(50, 20, 4000)) # Rle object is NOT expanded
A
#> <50 x 20 x 4000> RleArray object of type "integer":
#> ,,1
#> [,1] [,2] [,3] [,4] ... [,17] [,18] [,19] [,20]
#> [1,] 2 3 3 4 . 3 3 6 4
#> [2,] 2 3 3 4 . 3 3 6 4
#> ... . . . . . . . . .
#> [49,] 3 3 4 5 . 3 6 4 1
#> [50,] 3 3 4 5 . 3 6 4 1
#>
#> ...
#>
#> ,,4000
#> [,1] [,2] [,3] [,4] ... [,17] [,18] [,19] [,20]
#> [1,] 5 4 4 5 . 3 5 6 4
#> [2,] 5 4 4 5 . 3 5 6 4
#> ... . . . . . . . . .
#> [49,] 4 4 5 1 . 5 6 4 3
#> [50,] 4 4 5 1 . 5 6 4 3
#>
object.size(a)
#> 16000224 bytes
object.size(A)
#> 3335656 bytes
stopifnot(identical(a, as.array(A)))
as(A, "Rle") # deconstruction
#> integer-Rle of length 4000000 with 416605 runs
#> Lengths: 32 8 8 8 16 8 8 8 8 8 8 ... 16 8 16 16 8 8 24 8 16 8
#> Values : 2 5 1 3 6 4 5 2 3 1 5 ... 1 2 6 1 4 3 4 3 6 3
toto <- function(x) (5 * x[ , , 1] ^ 3 + 1L) * log(x[, , 2])
m1 <- toto(a)
head(m1)
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> [1,] 73.46214 0 243.679288 352.6545 1187.6 867.8203 10.75056 1121.6414
#> [2,] 73.46214 0 243.679288 352.6545 1187.6 867.8203 10.75056 1121.6414
#> [3,] 73.46214 0 243.679288 222.5002 1187.6 867.8203 10.75056 433.9101
#> [4,] 73.46214 0 243.679288 222.5002 1187.6 867.8203 10.75056 433.9101
#> [5,] 73.46214 0 6.591674 222.5002 1187.6 867.8203 28.41903 433.9101
#> [6,] 73.46214 0 6.591674 222.5002 1187.6 867.8203 28.41903 433.9101
#> [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16]
#> [1,] 6.591674 10.75056 28.41903 0.0000 149.4113 0 218.8836 687.7313
#> [2,] 6.591674 10.75056 28.41903 0.0000 149.4113 0 218.8836 687.7313
#> [3,] 6.591674 10.75056 28.41903 433.9101 149.4113 0 218.8836 749.2921
#> [4,] 6.591674 10.75056 28.41903 433.9101 149.4113 0 218.8836 749.2921
#> [5,] 6.591674 10.75056 687.73129 433.9101 149.4113 0 0.0000 749.2921
#> [6,] 6.591674 10.75056 687.73129 433.9101 149.4113 0 0.0000 749.2921
#> [,17] [,18] [,19] [,20]
#> [1,] 243.6793 149.4113 1187.599884 0.0000
#> [2,] 243.6793 149.4113 1187.599884 0.0000
#> [3,] 243.6793 149.4113 1187.599884 687.7313
#> [4,] 243.6793 149.4113 1187.599884 687.7313
#> [5,] 243.6793 149.4113 9.656627 687.7313
#> [6,] 243.6793 149.4113 9.656627 687.7313
M1 <- toto(A) # very fast! (operations are delayed)
M1
#> <50 x 20> DelayedMatrix object of type "double":
#> [,1] [,2] [,3] ... [,19] [,20]
#> [1,] 73.462138 0.000000 243.679288 . 1187.599884 0.000000
#> [2,] 73.462138 0.000000 243.679288 . 1187.599884 0.000000
#> [3,] 73.462138 0.000000 243.679288 . 1187.599884 687.731293
#> [4,] 73.462138 0.000000 243.679288 . 1187.599884 687.731293
#> [5,] 73.462138 0.000000 6.591674 . 9.656627 687.731293
#> ... . . . . . .
#> [46,] 10.75056 65.98695 352.65454 . 0 0
#> [47,] 10.75056 243.67929 352.65454 . 0 0
#> [48,] 10.75056 243.67929 352.65454 . 0 0
#> [49,] 0.00000 243.67929 352.65454 . 0 0
#> [50,] 0.00000 243.67929 352.65454 . 0 0
stopifnot(identical(m1, as.array(M1)))
cs <- colSums(m1)
CS <- colSums(M1)
stopifnot(identical(cs, CS))
## Coercing a DelayedMatrix object to DataFrame produces a DataFrame
## object with Rle columns:
as(M1, "DataFrame")
#> DataFrame with 50 rows and 20 columns
#> V1 V2 V3 V4
#> <Rle> <Rle> <Rle> <Rle>
#> 1 73.4621382383502 0 243.679287815015 352.654544662463
#> 2 73.4621382383502 0 243.679287815015 352.654544662463
#> 3 73.4621382383502 0 243.679287815015 222.500244959742
#> 4 73.4621382383502 0 243.679287815015 222.500244959742
#> 5 73.4621382383502 0 6.59167373200866 222.500244959742
#> ... ... ... ... ...
#> 46 10.7505568153683 65.9869544097981 352.654544662463 0
#> 47 10.7505568153683 243.679287815015 352.654544662463 0
#> 48 10.7505568153683 243.679287815015 352.654544662463 0
#> 49 0 243.679287815015 352.654544662463 0
#> 50 0 243.679287815015 352.654544662463 0
#> V5 V6 V7 V8
#> <Rle> <Rle> <Rle> <Rle>
#> 1 1187.59988405023 867.820270061051 10.7505568153683 1121.64142773676
#> 2 1187.59988405023 867.820270061051 10.7505568153683 1121.64142773676
#> 3 1187.59988405023 867.820270061051 10.7505568153683 433.910135030526
#> 4 1187.59988405023 867.820270061051 10.7505568153683 433.910135030526
#> 5 1187.59988405023 867.820270061051 28.4190344029578 433.910135030526
#> ... ... ... ... ...
#> 46 433.910135030526 0 1121.64142773676 222.500244959742
#> 47 433.910135030526 10.7505568153683 1121.64142773676 222.500244959742
#> 48 433.910135030526 10.7505568153683 1121.64142773676 222.500244959742
#> 49 867.820270061051 10.7505568153683 1121.64142773676 222.500244959742
#> 50 867.820270061051 10.7505568153683 1121.64142773676 222.500244959742
#> V9 V10 V11 V12
#> <Rle> <Rle> <Rle> <Rle>
#> 1 6.59167373200866 10.7505568153683 28.4190344029578 0
#> 2 6.59167373200866 10.7505568153683 28.4190344029578 0
#> 3 6.59167373200866 10.7505568153683 28.4190344029578 433.910135030526
#> 4 6.59167373200866 10.7505568153683 28.4190344029578 433.910135030526
#> 5 6.59167373200866 10.7505568153683 687.731292706237 433.910135030526
#> ... ... ... ... ...
#> 46 0 575.154789622206 0 352.654544662463
#> 47 0 28.4190344029578 0 352.654544662463
#> 48 0 28.4190344029578 0 352.654544662463
#> 49 10.7505568153683 28.4190344029578 0 352.654544662463
#> 50 10.7505568153683 28.4190344029578 0 352.654544662463
#> V13 V14 V15 V16
#> <Rle> <Rle> <Rle> <Rle>
#> 1 149.411271258863 0 218.883556091038 687.731292706237
#> 2 149.411271258863 0 218.883556091038 687.731292706237
#> 3 149.411271258863 0 218.883556091038 749.292102185301
#> 4 149.411271258863 0 218.883556091038 749.292102185301
#> 5 149.411271258863 0 0 749.292102185301
#> ... ... ... ... ...
#> 46 0 6.59167373200866 687.731292706237 1121.64142773676
#> 47 0 218.883556091038 687.731292706237 1121.64142773676
#> 48 0 218.883556091038 687.731292706237 1121.64142773676
#> 49 0 218.883556091038 687.731292706237 1121.64142773676
#> 50 0 218.883556091038 687.731292706237 1121.64142773676
#> V17 V18 V19 V20
#> <Rle> <Rle> <Rle> <Rle>
#> 1 243.679287815015 149.411271258863 1187.59988405023 0
#> 2 243.679287815015 149.411271258863 1187.59988405023 0
#> 3 243.679287815015 149.411271258863 1187.59988405023 687.731292706237
#> 4 243.679287815015 149.411271258863 1187.59988405023 687.731292706237
#> 5 243.679287815015 149.411271258863 9.6566274746046 687.731292706237
#> ... ... ... ... ...
#> 46 222.500244959742 56.8380688059155 0 0
#> 47 222.500244959742 1187.59988405023 0 0
#> 48 222.500244959742 1187.59988405023 0 0
#> 49 149.411271258863 1187.59988405023 0 0
#> 50 149.411271258863 1187.59988405023 0 0
## ---------------------------------------------------------------------
## B. MAKING AN RleArray OBJECT FROM A LIST-LIKE OBJECT OF Rle OBJECTS
## ---------------------------------------------------------------------
## From a DataFrame object:
DF <- DataFrame(A=Rle(sample(3L, 100, replace=TRUE)),
B=Rle(sample(3L, 100, replace=TRUE)),
C=Rle(sample(3L, 100, replace=TRUE) - 0.5),
row.names=sprintf("ID%03d", 1:100))
M2 <- RleArray(DF)
M2
#> <100 x 3> RleMatrix object of type "double":
#> A B C
#> ID001 1.0 1.0 1.5
#> ID002 2.0 3.0 1.5
#> ID003 2.0 2.0 0.5
#> ID004 3.0 2.0 2.5
#> ID005 3.0 3.0 2.5
#> ... . . .
#> ID096 1.0 1.0 0.5
#> ID097 3.0 3.0 1.5
#> ID098 1.0 2.0 0.5
#> ID099 3.0 3.0 1.5
#> ID100 1.0 2.0 2.5
A3 <- RleArray(DF, dim=c(25, 6, 2))
A3
#> <25 x 6 x 2> RleArray object of type "double":
#> ,,1
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 1 1 3 2 1 3
#> [2,] 2 3 2 3 3 3
#> ... . . . . . .
#> [24,] 1 1 3 3 3 1
#> [25,] 2 2 2 1 2 2
#>
#> ,,2
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 3.0 2.0 1.5 2.5 2.5 1.5
#> [2,] 2.0 3.0 1.5 2.5 1.5 0.5
#> ... . . . . . .
#> [24,] 1.0 3.0 0.5 1.5 1.5 1.5
#> [25,] 3.0 2.0 0.5 1.5 1.5 2.5
#>
M4 <- RleArray(DF, dim=c(25, 12), dimnames=list(LETTERS[1:25], NULL))
M4
#> <25 x 12> RleMatrix object of type "double":
#> [,1] [,2] [,3] ... [,11] [,12]
#> A 1 1 3 . 2.5 1.5
#> B 2 3 2 . 1.5 0.5
#> C 2 1 1 . 0.5 2.5
#> D 3 1 2 . 2.5 0.5
#> E 3 1 3 . 2.5 2.5
#> . . . . . . .
#> U 3 3 2 . 1.5 0.5
#> V 2 2 1 . 0.5 1.5
#> W 2 1 2 . 2.5 0.5
#> X 1 1 3 . 1.5 1.5
#> Y 2 2 2 . 1.5 2.5
## From an ordinary list:
## If all the supplied Rle objects have the same length and if the 'dim'
## argument is not specified, then the RleArray() constructor returns an
## RleMatrix object with 1 column per Rle object. If the 'dimnames'
## argument is not specified, then the names on the list are propagated
## as the colnames of the returned object.
data <- as.list(DF)
M2b <- RleArray(data)
A3b <- RleArray(data, dim=c(25, 6, 2))
M4b <- RleArray(data, dim=c(25, 12), dimnames=list(LETTERS[1:25], NULL))
data2 <- list(Rle(sample(3L, 9, replace=TRUE)) * 11L,
Rle(sample(3L, 15, replace=TRUE)))
if (FALSE) { # \dontrun{
RleArray(data2) # error! (cannot infer the dim)
} # }
RleArray(data2, dim=c(4, 6))
#> <4 x 6> RleMatrix object of type "integer":
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 11 33 33 2 1 2
#> [2,] 22 33 3 3 3 3
#> [3,] 22 11 3 1 3 2
#> [4,] 22 11 3 1 1 3
## From an RleList object:
data <- RleList(data)
M2c <- RleArray(data)
A3c <- RleArray(data, dim=c(25, 6, 2))
M4c <- RleArray(data, dim=c(25, 12), dimnames=list(LETTERS[1:25], NULL))
data2 <- RleList(data2)
if (FALSE) { # \dontrun{
RleArray(data2) # error! (cannot infer the dim)
} # }
RleArray(data2, dim=4:2)
#> <4 x 3 x 2> RleArray object of type "integer":
#> ,,1
#> [,1] [,2] [,3]
#> [1,] 11 33 33
#> [2,] 22 33 3
#> [3,] 22 11 3
#> [4,] 22 11 3
#>
#> ,,2
#> [,1] [,2] [,3]
#> [1,] 2 1 2
#> [2,] 3 3 3
#> [3,] 1 3 2
#> [4,] 1 1 3
#>
## Sanity checks:
data0 <- as.vector(unlist(DF, use.names=FALSE))
m2 <- matrix(data0, ncol=3, dimnames=dimnames(M2))
stopifnot(identical(m2, as.matrix(M2)))
rownames(m2) <- NULL
stopifnot(identical(m2, as.matrix(M2b)))
stopifnot(identical(m2, as.matrix(M2c)))
a3 <- array(data0, dim=c(25, 6, 2))
stopifnot(identical(a3, as.array(A3)))
stopifnot(identical(a3, as.array(A3b)))
stopifnot(identical(a3, as.array(A3c)))
m4 <- matrix(data0, ncol=12, dimnames=dimnames(M4))
stopifnot(identical(m4, as.matrix(M4)))
stopifnot(identical(m4, as.matrix(M4b)))
stopifnot(identical(m4, as.matrix(M4c)))
## ---------------------------------------------------------------------
## C. COERCING FROM RleList OR DataFrame TO RleMatrix
## ---------------------------------------------------------------------
## Coercing an RleList object to RleMatrix only works if all the list
## elements in the former have the same length.
x <- RleList(A=Rle(sample(3L, 20, replace=TRUE)),
B=Rle(sample(3L, 20, replace=TRUE)))
M <- as(x, "RleMatrix")
stopifnot(identical(x, as(M, "RleList")))
x <- DataFrame(A=x[[1]], B=x[[2]], row.names=letters[1:20])
M <- as(x, "RleMatrix")
stopifnot(identical(x, as(M, "DataFrame")))
## ---------------------------------------------------------------------
## D. CONSTRUCTING A LARGE RleArray OBJECT
## ---------------------------------------------------------------------
## The RleArray() constructor does not accept a "long" Rle object (i.e.
## an object of length > .Machine$integer.max) at the moment:
if (FALSE) { # \dontrun{
RleArray(Rle(5, 3e9), dim=c(3, 1e9)) # error!
} # }
## The workaround is to supply a list of Rle objects instead:
toy_Rle <- function() {
run_lens <- c(sample(4), sample(rep(c(1:19, 40) * 3, 6e4)), sample(4))
run_vals <- sample(700, length(run_lens), replace=TRUE) / 5
Rle(run_vals, run_lens)
}
rle_list <- lapply(1:80, function(j) toy_Rle()) # takes about 20 sec.
## Cumulative length of all the Rle objects is > .Machine$integer.max:
sum(lengths(rle_list)) # 3.31e+09
#> [1] 3312001600
## Feed 'rle_list' to the RleArray() constructor:
dim <- c(14395, 320, 719)
A <- RleArray(rle_list, dim)
A
#> <14395 x 320 x 719> RleArray object of type "double":
#> ,,1
#> [,1] [,2] [,3] ... [,319] [,320]
#> [1,] 72.4 106.6 57.8 . 94.8 135.4
#> [2,] 72.4 106.6 57.8 . 94.8 135.4
#> ... . . . . . .
#> [14394,] 125.0 85.0 71.2 . 135.4 85.2
#> [14395,] 125.0 57.8 71.2 . 135.4 85.2
#>
#> ...
#>
#> ,,719
#> [,1] [,2] [,3] ... [,319] [,320]
#> [1,] 40.6 132.6 33.4 . 116.4 47.2
#> [2,] 40.6 132.6 33.4 . 116.4 47.2
#> ... . . . . . .
#> [14394,] 132.6 33.4 89.0 . 47.2 31.4
#> [14395,] 132.6 33.4 89.0 . 47.2 17.2
#>
## Because all the Rle objects in 'rle_list' have the same length, we
## can call RleArray() on it without specifying the 'dim' argument. This
## returns an RleMatrix object where each column corresponds to an Rle
## object in 'rle_list':
M <- RleArray(rle_list)
M
#> <41400020 x 80> RleMatrix object of type "double":
#> [,1] [,2] [,3] ... [,79] [,80]
#> [1,] 72.4 42.0 135.4 . 72.4 87.6
#> [2,] 72.4 53.8 135.4 . 113.8 87.6
#> [3,] 128.6 53.8 135.4 . 113.8 87.6
#> [4,] 48.2 4.6 135.4 . 113.8 85.8
#> [5,] 48.2 4.6 76.0 . 110.6 50.0
#> ... . . . . . .
#> [41400016,] 102.0 89.8 43.0 . 17.8 48.8
#> [41400017,] 94.8 89.8 1.4 . 60.4 48.8
#> [41400018,] 94.8 9.2 1.4 . 60.4 31.4
#> [41400019,] 94.8 121.8 1.4 . 60.4 31.4
#> [41400020,] 94.8 121.8 1.4 . 19.2 17.2
stopifnot(identical(as(rle_list, "RleList"), as(M, "RleList")))
## ---------------------------------------------------------------------
## E. CHANGING THE TYPE OF AN RleArray OBJECT FROM "double" TO "integer"
## ---------------------------------------------------------------------
## An RleArray object is an in-memory object so it can be useful to
## reduce its memory footprint. For an object of type "double" this can
## be done by changing its type to "integer" (integers are half the size
## of doubles in memory). Of course this only makes sense if this results
## in a loss of precision that is acceptable.
## On an ordinary array (or matrix) 'a', this is simply a matter of
## doing 'storage.mode(a) <- "integer"'. However, with a DelayedArray
## object, things are a little bit different. Let's do this on a subset
## of the RleMatrix object 'M' created in the previous section.
M1 <- as(M[1:6e5, ], "RleMatrix")
rm(M)
## First of all, it's important to be aware that object.size() (from
## package utils) is NOT reliable on RleArray objects! This is because
## the data in an RleArray object is stored in an environment and
## object.size() stubbornly refuses to take the content of an environment
## into account when computing its size:
object.size(list2env(list(aa=1:10))) # 56 bytes
#> 56 bytes
object.size(list2env(list(aa=1:1e6))) # always 56 bytes!
#> 56 bytes
## So we'll use obj_size() instead (from package lobstr):
library(lobstr)
obj_size(list2env(list(aa=1:10))) # 264 B
#> 848 B
obj_size(list2env(list(aa=1:1e6))) # 4 MB
#> 848 B
obj_size(list2env(list(aa=as.double(1:1e6)))) # 8 MB
#> 848 B
obj_size(M1) # 16.7 MB
#> 16.70 MB
type(M1) <- "integer" # Delayed!
M1 # Note the class: it's no longer RleMatrix!
#> <600000 x 80> DelayedMatrix object of type "integer":
#> [,1] [,2] [,3] [,4] ... [,77] [,78] [,79] [,80]
#> [1,] 72 42 135 36 . 20 71 72 87
#> [2,] 72 53 135 120 . 107 71 113 87
#> [3,] 128 53 135 120 . 107 71 113 87
#> [4,] 48 4 135 120 . 107 71 113 85
#> [5,] 48 4 76 120 . 107 135 110 50
#> ... . . . . . . . . .
#> [599996,] 122 81 41 38 . 102 86 132 138
#> [599997,] 122 81 41 38 . 102 86 132 138
#> [599998,] 122 81 41 38 . 102 86 132 138
#> [599999,] 122 84 41 38 . 102 86 96 138
#> [600000,] 122 84 41 38 . 102 86 96 138
# (That's because the object now carries delayed
# operations.)
## Because changing the type is a delayed operation, the memory footprint
## of the object has not changed yet (remember that the original data in
## a DelayedArray object is stored in its "seed" and its seed is never
## modified **in-place**, that is, no operation on the object will ever
## modify its seed):
obj_size(M1) # Still the same (well, a very tiny more, because the
#> 16.71 MB
# object is now carrying one more delayed operation,
# the `type<-` operation)
## To effectively reduce the memory footprint of the object, a new object
## needs to be created. This is achieved simply by **realizing** M1 as a
## (new) RleArray object. Note that this realization will use block
## processing:
DelayedArray:::set_verbose_block_processing(TRUE) # See block processing
#> [1] FALSE
# in action.
getAutoBlockSize() # Automatic block size (100 Mb by default).
#> [1] 1e+08
setAutoBlockSize(20e6) # Set automatic block size to 20 Mb.
#> automatic block size set to 2e+07 bytes (was 1e+08)
M2 <- as(M1, "RleArray")
#> / reading and realizing block 1/10 ...
#> ok
#> \ Writing it ...
#> OK
#> / reading and realizing block 2/10 ...
#> ok
#> \ Writing it ...
#> OK
#> / reading and realizing block 3/10 ...
#> ok
#> \ Writing it ...
#> OK
#> / reading and realizing block 4/10 ...
#> ok
#> \ Writing it ...
#> OK
#> / reading and realizing block 5/10 ...
#> ok
#> \ Writing it ...
#> OK
#> / reading and realizing block 6/10 ...
#> ok
#> \ Writing it ...
#> OK
#> / reading and realizing block 7/10 ...
#> ok
#> \ Writing it ...
#> OK
#> / reading and realizing block 8/10 ...
#> ok
#> \ Writing it ...
#> OK
#> / reading and realizing block 9/10 ...
#> ok
#> \ Writing it ...
#> OK
#> / reading and realizing block 10/10 ...
#> ok
#> \ Writing it ...
#> OK
DelayedArray:::set_verbose_block_processing(FALSE)
#> [1] TRUE
setAutoBlockSize() # Reset automatic block size to factory settings.
#> automatic block size set to 1e+08 bytes (was 2e+07)
M2
#> <600000 x 80> RleMatrix object of type "integer":
#> [,1] [,2] [,3] [,4] ... [,77] [,78] [,79] [,80]
#> [1,] 72 42 135 36 . 20 71 72 87
#> [2,] 72 53 135 120 . 107 71 113 87
#> [3,] 128 53 135 120 . 107 71 113 87
#> [4,] 48 4 135 120 . 107 71 113 85
#> [5,] 48 4 76 120 . 107 135 110 50
#> ... . . . . . . . . .
#> [599996,] 122 81 41 38 . 102 86 132 138
#> [599997,] 122 81 41 38 . 102 86 132 138
#> [599998,] 122 81 41 38 . 102 86 132 138
#> [599999,] 122 84 41 38 . 102 86 96 138
#> [600000,] 122 84 41 38 . 102 86 96 138
obj_size(M2) # 6.91 MB (Less than half the original size! This is
#> 6.92 MB
# because RleArray objects use some internal tricks to
# reduce memory footprint even more when the data in
# their seed is of type "integer".)
## Finally note that the 2-step approach described here (i.e.
## type(A) <- "integer" followed by realization) is generic and works
## on any kind of DelayedArray object or derivative. In particular,
## after doing 'type(A) <- "integer"', 'A' can be realized as anything
## as long as the realization backend is supported (e.g. could be
## 'as(A, "HDF5Array")' or 'as(A, "TENxMatrix")') and realization will
## always use block processing so the array data will never be fully
## loaded in memory.