Skip to contents

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.

Usage

container(...)

cont(...)

as.container(x)

as.cont(x)

is.container(x)

# S3 method for class 'Container'
as.list(x, ...)

# S3 method for class 'Container'
length(x)

# S3 method for class 'Container'
names(x)

# S3 method for class 'Container'
names(x) <- value

Arguments

...

(possibly named) elements to be put into or removed from the Container, or additional arguments passed from and to methods.

x

R object of ANY type for as.container and is.container or of class Container for the S3 methods.

value

character vector of names.

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 for container(...).

  • as.container(x) or as.cont(x) coerce x to a Container

  • as.list(x) converts container x 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 in x.

  • names(x) return the names of the elements contained in x.

  • names(x) <- value sets the names of x.

  • x + y combines x and y into a new container by appending y to x.

  • x - y element-wise discards all items of y from x, given the element was contained in x. The result is always a container.

  • x == y is TRUE if the contents of x and y are lexicographically equal.

  • x != y is TRUE if the contents of x and y are not equal.

  • x < y is TRUE if the contents of x are lexicographically less than the contents of y.

  • x <= y is TRUE if the contents of x are lexicographically less than or equal to the contents of y.

  • add(.x, ...) and ref_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) and ref_clear(x) remove all elements from x.

  • clone(x) create a copy of x.

  • count(x, elem) count how often elem occurs in x.

  • delete(.x, ...) and ref_delete(.x, ...) find and remove elements. If one or more elements don't exist, an error is signaled.

  • delete_at(.x, ...) and ref_delete_at(.x, ...) find and remove values at given indices. If any given index is invalid, an error is signaled.

  • discard(.x, ...) and ref_discard(.x, ...) find and discard elements. Elements that don't exist, are ignored.

  • discard_at(.x, ...) and ref_discard_at(.x, ...) find and discard values at given indices. Invalid indices are ignored.

  • has(x, elem) TRUE if element is in x and otherwise FALSE.

  • has_name(x, name) check if name is in x

  • is_empty(x) TRUE if object is empty otherwise FALSE

  • 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 the container object.

  • rename(.x, old, new) and ref_rename(.x, old, new) rename one or more keys from old to new, respectively, by copy and in place (i.e. by reference).

  • replace(.x, old, new, add = FALSE) and ref_replace(.x, old, new, add = FALSE) try to find element old and replace it with element new. If old does not exist, an error is raised, unless add was set to TRUE.

  • replace_at(.x, .., .add = FALSE) and ref_replace_at(.x, ..., .add = FALSE) replace values at given indices. If a given index is invalid, an error is signaled unless .add was set to TRUE.

See also

For the class documentation see Container. Objects of the derived classes can be created by deque, setnew, and dict.

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]