Container - Enhancing R's list
Source:R/0-ContainerS3.R
, R/GroupGenericMath.R
, R/GroupGenericSummary.R
, and 23 more
ContainerS3.Rd
A container is a data structure with typical member functions to insert, delete and access elements from the container object. It can be considered as a base R list with extended functionality. The Container class also serves as the base class for Deque, Set, and Dict objects.
Details
Methods that alter Container objects usually come in two versions
providing either copy or reference semantics where the latter start with
'ref_'
to note the reference semantic, for example, add()
and ref_add()
.
container(...)
initializes and returns a Container object.
cont(...)
is a short cut forcontainer(...)
.
as.container(x)
oras.cont(x)
coercex
to a Container
is.container(x)
check ifx
is a Container
as.list(x)
converts containerx
to a base R list. All of the container's elements are copied (deeply) during the conversion.
length(x)
return the number of elements contained inx
.
names(x)
return the names of the elements contained inx
.
names(x) <- value
sets the names ofx
.
x + y
combinesx
andy
into a new container by appendingy
tox
.
x - y
element-wise discards all items ofy
fromx
, given the element was contained inx
. The result is always a container.
x == y
isTRUE
if the contents ofx
andy
are lexicographically equal.
x != y
isTRUE
if the contents ofx
andy
are not equal.
x < y
isTRUE
if the contents of x are lexicographically less than the contents of y.
x <= y
isTRUE
if the contents of x are lexicographically less than or equal to the contents of y.
add(.x, ...)
andref_add(.x, ...)
add elements to.x
.
at(.x, ...,)
returns the value at the given indices. Indices can be letters or numbers or both. All indices must exist.
at2(x, index)
returns the value at the given index or signals an error if not found.
clear(x)
andref_clear(x)
remove all elements fromx
.
clone(x)
create a copy ofx
.
count(x, elem)
count how oftenelem
occurs inx
.
delete(.x, ...)
andref_delete(.x, ...)
find and remove elements. If one or more elements don't exist, an error is signaled.
delete_at(.x, ...)
andref_delete_at(.x, ...)
find and remove values at given indices. If any given index is invalid, an error is signaled.
discard(.x, ...)
andref_discard(.x, ...)
find and discard elements. Elements that don't exist, are ignored.
discard_at(.x, ...)
andref_discard_at(.x, ...)
find and discard values at given indices. Invalid indices are ignored.
has(x, elem)
TRUE
if element is inx
and otherwiseFALSE
.
has_name(x, name)
check ifname
is inx
is_empty(x)
TRUE
if object is empty otherwiseFALSE
peek_at(x, ..., .default = NULL)
returns the value at the given indices or (if not found) the given default value.
peek_at2(x, index, default)
returns the value at the given index or (if not found) the given default value.
ref_pop(.x, index)
return element at given index and remove it from thecontainer
object.
rename(.x, old, new)
andref_rename(.x, old, new)
rename one or more keys fromold
tonew
, respectively, by copy and in place (i.e. by reference).
replace(.x, old, new, add = FALSE)
andref_replace(.x, old, new, add = FALSE)
try to find elementold
and replace it with elementnew
. Ifold
does not exist, an error is raised, unlessadd
was set toTRUE
.
replace_at(.x, .., .add = FALSE)
andref_replace_at(.x, ..., .add = FALSE)
replace values at given indices. If a given index is invalid, an error is signaled unless.add
was set toTRUE
.
Examples
co = container(1:5, c = container("a", 1), l = list())
is.container(co)
#> [1] TRUE
print(co)
#> [(1L 2L 3L 4L ...), c = ["a", 1], l = list()]
length(co)
#> [1] 3
names(co)
#> [1] "" "c" "l"
unpack(co) # flatten recursively similar to unlist
#> c1 c2
#> "1" "2" "3" "4" "5" "a" "1"
# Math
co = container(1, 2, -(3:5))
co
#> [1, 2, (-3L -4L -5L)]
abs(co)
#> [1, 2, 3, 4, 5]
cumsum(co)
#> [1, 3, 0, -4, -9]
round(co)
#> [1, 2, -3, -4, -5]
exp(co)
#> [2.718282, 7.389056, 0.04978707, 0.01831564, 0.006737947]
# Summary
range(co)
#> [1] -5 2
min(co)
#> [1] -5
max(co)
#> [1] 2
# Arithmetic
c1 = container(1, 1:2)
c2 = container(2, 1:2)
c1 + c2 # same as c(c1, c2)
#> [1, (1L 2L), 2, (1L 2L)]
c2 + c1 # same as c(c2, c1)
#> [2, (1L 2L), 1, (1L 2L)]
c1 - c2
#> [1]
c2 - c1
#> [2]
c1 - c1
#> []
# Comparison
c1 = container(1, 2, 3)
c2 = container(1, 3, 2)
c1 == c1 # TRUE
#> [1] TRUE
c1 != c2 # TRUE
#> [1] TRUE
c1 <= c1 # TRUE
#> [1] TRUE
c1 == c2 # FALSE
#> [1] FALSE
c1 < c2 # TRUE
#> [1] TRUE
c1 < container(2) # TRUE
#> [1] TRUE
c1 < container() # FALSE
#> [1] FALSE
# Extract or replace
co = container(a = 1, b = 2, c = 3, d = 4)
co[1:2]
#> [a = 1, b = 2]
co[1, 4]
#> [a = 1, d = 4]
co["d", 2]
#> [d = 4, b = 2]
co[list("d", 2)]
#> [d = 4, b = 2]
co[0:10]
#> [a = 1, b = 2, c = 3, d = 4]
co = container(a = 1, b = 2)
co[[1]]
#> [1] 1
co[["a"]]
#> [1] 1
co[["x"]]
#> NULL
co = container(a = 1, b = "bar")
(co[1:2] <- 1:2)
#> [1] 1 2
try({
co[3] <- 3 # index out of range
})
#> Error : index out of range (length = 2): 3
(co[list(1, "b")] <- 3:4) # mixed numeric/character index
#> [1] 3 4
co = container(a = 1, b = 2)
co[[1]] <- 9
co[["b"]] <- 8
co[["x"]] <- 7
co$z <- 99
print(co)
#> [a = 9, b = 8, x = 7, z = 99]
# Replace 8 by 0
co[[{8}]] <- 0
print(co)
#> [a = 9, b = 0, x = 7, z = 99]
co = container(a = 1, b = "bar")
co$f <- 3
co$b <- 2
co
#> [a = 1, b = 2, f = 3]
co = container(1)
add(co, 1, b = 2, c = container(1:3))
#> [1, 1, b = 2, c = [(1L 2L 3L)]]
co = container(a = 1, 2, b = 3, 4)
at(co, 1:3)
#> [a = 1, 2, b = 3]
at(co, "a", "b", 2)
#> [a = 1, b = 3, 2]
try(at(co, "x")) # index 'x' not found
#> Error : index 'x' not found
try(at(co, 1:10)) # index 5 exceeds length of Container
#> Error : index 5 exceeds length of Container, which is 4
co = container(a = 1, 2, b = 3, 4)
at2(co, 1)
#> [1] 1
at2(co, "a")
#> [1] 1
at2(co, 2)
#> [1] 2
try(at2(co, "x")) # index 'x' not found
#> Error : index 'x' not found
try(at2(co, 5)) # index 5 exceeds length of Container
#> Error : index 5 exceeds length of Container, which is 4
co = container(1, 2, mean)
clear(co)
#> []
print(co) # Original was not touched
#> [1, 2, <<function>>]
ref_clear(co) # Clears original
print(co)
#> []
co = container(1, 2, 3)
co2 = clone(co)
co == co2
#> [1] TRUE
co = container("a", "b", "a", mean, mean)
count(co, "a")
#> [1] 2
count(co, mean)
#> [1] 2
count(co, "c")
#> [1] 0
co = container("a", 1:3, iris)
print(co)
#> ["a", (1L 2L 3L), <<data.frame(150x5)>>]
delete(co, 1:3, "a")
#> [<<data.frame(150x5)>>]
delete(co, iris)
#> ["a", (1L 2L 3L)]
try({
delete(co, "b") # "b" is not in Container
})
#> Error : "b" is not in Container
co = container(a = 1, b = 2, 3)
delete_at(co, "a", "b") # [3]
#> [3]
delete_at(co, 1:2) # [3]
#> [3]
delete_at(co, "a", 3) # [b = 2]
#> [b = 2]
try({
delete_at(co, 4) # index out of range
delete_at(co, "x") # names(s) not found: 'x'
})
#> Error : index out of range (length = 3): 4
co = container("a", num = 1:3, data = iris)
print(co)
#> ["a", num = (1L 2L 3L), data = <<data.frame(150x5)>>]
discard(co, 1:3, "a")
#> [data = <<data.frame(150x5)>>]
discard(co, iris)
#> ["a", num = (1L 2L 3L)]
discard(co, "b") # ignored
#> ["a", num = (1L 2L 3L), data = <<data.frame(150x5)>>]
co = container(a = 1, b = 2, 3)
discard_at(co, "a", "b") # [3]
#> [3]
discard_at(co, 1:2) # [3]
#> [3]
discard_at(co, "a", 3) # [b = 2]
#> [b = 2]
discard_at(co, "x") # ignored
#> [a = 1, b = 2, 3]
co = container(1, 2, mean)
has(co, 1) # TRUE
#> [1] TRUE
has(co, mean) # TRUE
#> [1] TRUE
has(co, 1:2) # FALSE
#> [1] FALSE
co = container(a = 1, 2, f = mean)
has_name(co, "a") # TRUE
#> [1] TRUE
has_name(co, "f") # TRUE
#> [1] TRUE
has_name(co, "2") # FALSE
#> [1] FALSE
co = container(1, 2)
is_empty(co)
#> [1] FALSE
is_empty(clear(co))
#> [1] TRUE
co = container(a = 1, 2, b = 3, 4)
peek_at(co, 1)
#> [a = 1]
peek_at(co, "a")
#> [a = 1]
peek_at(co, "x")
#> []
peek_at(co, "x", .default = 0)
#> [x = 0]
peek_at(co, "a", "x", 2, 9, .default = -1)
#> [a = 1, x = -1, 2, -1]
co = container(a = 1, 2, b = 3, 4)
peek_at2(co, 1)
#> [1] 1
peek_at2(co, "a")
#> [1] 1
peek_at2(co, "x")
#> NULL
peek_at2(co, "x", default = 0)
#> [1] 0
co = container(a = 1, b = 1:3, d = "foo")
ref_pop(co, "b")
#> [1] 1 2 3
ref_pop(co, 1)
#> [1] 1
try({
ref_pop(co, "x") # index 'x' not found
})
#> Error : index 'x' not found
co = container(a = 1, b = 2, 3)
rename(co, c("a", "b"), c("a1", "y"))
#> [a1 = 1, y = 2, 3]
print(co)
#> [a = 1, b = 2, 3]
ref_rename(co, c("a", "b"), c("a1", "y"))
#> [a1 = 1, y = 2, 3]
print(co)
#> [a1 = 1, y = 2, 3]
co = container("x", 9)
replace(co, 9, 0)
#> ["x", 0]
replace(co, "x", 0)
#> [0, 9]
try({
replace(co, "z", 0) # old element ("z") is not in Container
})
#> Error : old element ("z") is not in Container
replace(co, "z", 0, add = TRUE) # ok, adds the element
#> ["x", 9, 0]
co = container(a = 0, b = "z")
replace_at(co, a = 1, b = 2)
#> [a = 1, b = 2]
replace_at(co, 1:2, 1:2) # same
#> [a = 1L, b = 2L]
replace_at(co, c("a", "b"), list(1, 2)) # same
#> [a = 1, b = 2]
try({
replace_at(co, x = 1) # names(s) not found: 'x'
})
#> Error : names(s) not found: 'x'
replace_at(co, x = 1, .add = TRUE) # ok (adds x = 1)
#> [a = 0, b = "z", x = 1]