Skip to content

Instantly share code, notes, and snippets.

@coolbutuseless
Created January 20, 2018 01:05
Show Gist options
  • Save coolbutuseless/19568745e02c4ffae63d90e9283388d9 to your computer and use it in GitHub Desktop.
Save coolbutuseless/19568745e02c4ffae63d90e9283388d9 to your computer and use it in GitHub Desktop.
Use the 'bit' package to do boolean vector (with NA) with 2-bits per value.
library(bit)
library(R6)
#-----------------------------------------------------------------------------
# Outline of an R6 class to wrap a logical vector that may take values: TRUE, FALSE or NA
#
# This uses the 'bit' package for 2-bit booleans (1 bit for t/f and 1bit for NA status)
#
# This uses less memory than a normal logical vector (which uses 32 bits for
# each logical value)
#
# This reducation in memory will mean that some operations will be much
# faster as the vector grows. e.g. N = 2^30
#-----------------------------------------------------------------------------
TFNA <- R6::R6Class(
"TFNA",
public = list(
tf = NULL,
na = NULL,
initialize = function(N, type=c('false', 'random')) {
type <- match.arg(type)
t <- system.time({
if (type == 'false') {
# initialise to all false with no NAs
self$tf <- bit::bit(N)
self$na <- bit::bit(N)
} else {
# initialise T, F, NA in approximately 1:1:1 ratio
self$tf <- as.bit(sample(c(TRUE, FALSE ), N, replace=TRUE))
self$na <- as.bit(sample(c(TRUE, FALSE, FALSE), N, replace=TRUE))
}
})
cat("Initialisation time:", t[['elapsed']], "seconds\n")
},
get = function(i) {
if (self$na[i]) {
NA
} else {
self$tf[i]
}
},
count = function() {
t <- sum(!self$na & self$tf)
na <- sum(self$na)
list(true=t, false=length(self$na)-t-na, na=na)
},
print = function() {
print("True/False")
print(self$tf)
print("NA status")
print(self$na)
}
)
)
tfna <- TFNA$new(2^10-1, type='random')
tfna$count()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment