Lists

Reading Assignments

Lists vs Vectors

  • List vs Vector
  • Both are one-dimension
  • Non-atomic (allow mixed data type) vs Atomic (same data type)
    • Lists is non-atomic and allow combining elements of different data types without them being coerced.
    • Vector is atomic and doesn’t allow elements of different data types in one vector.

Example:

Vector cannot handle mixed data type \(\Rightarrow\) Coercion

### c() is used to create vector

investment1_specs = c(
  "deposit" = 1000,      # double
  "rate" = 0.02,         # double
  "years" = 4L,          # integer
  "account" = "savings"  # character
)
investment1_specs
#>   deposit      rate     years   account 
#>    "1000"    "0.02"       "4" "savings"

List can allow mixed data type.

### The only difference is list() is used to create list

specs1 = list(
  "deposit" = 1000,      # double
  "rate" = 0.02,         # double
  "years" = 4L,          # integer
  "account" = "savings"  # character
)

specs1
#> $deposit
#> [1] 1000
#> 
#> $rate
#> [1] 0.02
#> 
#> $years
#> [1] 4
#> 
#> $account
#> [1] "savings"

Create Lists – list()

You are strongly recommended to give names to the elements of a list.

Example 8.3

vec1 <- 1:3
vec2 <- 4:6
vec3 <- 7:9
  • List with unnamed elements

Example:

list_index <- list(vec1, vec2, vec3)
list_index
#> [[1]]
#> [1] 1 2 3
#> 
#> [[2]]
#> [1] 4 5 6
#> 
#> [[3]]
#> [1] 7 8 9
  • List with elements names

Example:

list_names <- list(vec1 = vec1, vec2 = vec2, vec3 = vec3)
# Equivalently
# list_names <- list("vec1" = vec1, "vec2" = vec2, "vec3" = vec3)
list_names
#> $vec1
#> [1] 1 2 3
#> 
#> $vec2
#> [1] 4 5 6
#> 
#> $vec3
#> [1] 7 8 9

Manipulating Lists

  • List with unnamed elements \(\rightarrow\) Use index [[]]

Example:

list_index[[2]]
#> [1] 4 5 6
  • List with elements names \(\rightarrow\) Use $ (recommended) or index [[]]

Example:

list_names$vec2
#> [1] 4 5 6
# We can still use index [[]] for lists with elements names
list_names[[2]]
#> [1] 4 5 6

Further manipulate the elements in the vector vec2

list_names$vec2[3] # Third element in vec2
#> [1] 6
list_names[[2]][3]
#> [1] 6

Single Bracket [] vs Double Bracket for list

list_names[2]
#> $vec2
#> [1] 4 5 6
list_names[[2]]
#> [1] 4 5 6

Adding New Elements

Using index [[]]

list_names[[4]] <- c("A", "B", "C")
list_names
#> $vec1
#> [1] 1 2 3
#> 
#> $vec2
#> [1] 4 5 6
#> 
#> $vec3
#> [1] 7 8 9
#> 
#> [[4]]
#> [1] "A" "B" "C"

Using names

list_names$vec5 <- c(TRUE, FALSE, TRUE)
list_names
#> $vec1
#> [1] 1 2 3
#> 
#> $vec2
#> [1] 4 5 6
#> 
#> $vec3
#> [1] 7 8 9
#> 
#> [[4]]
#> [1] "A" "B" "C"
#> 
#> $vec5
#> [1]  TRUE FALSE  TRUE

Removing Elements

  • Unnamed
list_names[[4]] <- NULL
list_names
#> $vec1
#> [1] 1 2 3
#> 
#> $vec2
#> [1] 4 5 6
#> 
#> $vec3
#> [1] 7 8 9
#> 
#> $vec5
#> [1]  TRUE FALSE  TRUE
  • Named
list_names$vec5 <- NULL
list_names
#> $vec1
#> [1] 1 2 3
#> 
#> $vec2
#> [1] 4 5 6
#> 
#> $vec3
#> [1] 7 8 9

Generic Vector

Chapter 6 Generic Vectors in Atomic R https://book.stat385.org/generic-vectors.html

  • Lists = generic vectors \(\quad \leftarrow \quad\) is.list()
  • Vectors = atomic vectors\(\quad \leftarrow \quad\) is.atomic()

c() function can be used to create lists?

If coercion to an atomic vector is not possible, the result will be a list.

Example:

list(1)
#> [[1]]
#> [1] 1

typeof(list(1))
#> [1] "list"

c(list(1), 1)
#> [[1]]
#> [1] 1
#> 
#> [[2]]
#> [1] 1
typeof(c(list(1), 1))
#> [1] "list"
is.list(c(list(1),1))
#> [1] TRUE

list of a list

lst <- list(
  a = 1:10,
  b = "Hello, World!",
  d = list(a = 1, b = "z")
)

typeof(lst)
#> [1] "list"
lst
#> $a
#>  [1]  1  2  3  4  5  6  7  8  9 10
#> 
#> $b
#> [1] "Hello, World!"
#> 
#> $d
#> $d$a
#> [1] 1
#> 
#> $d$b
#> [1] "z"

unlist() force a list to be an atomic vector

Necessary coercion may take place

unlist(lst)
#>              a1              a2              a3              a4              a5 
#>             "1"             "2"             "3"             "4"             "5" 
#>              a6              a7              a8              a9             a10 
#>             "6"             "7"             "8"             "9"            "10" 
#>               b             d.a             d.b 
#> "Hello, World!"             "1"             "z"
bar = list(a = 1:10,
           b = "Hello, World!",
           c = log,
           d = list(a = 1, b = "z"))
unlist(bar)
#> $a1
#> [1] 1
#> 
#> $a2
#> [1] 2
#> 
#> $a3
#> [1] 3
#> 
#> $a4
#> [1] 4
#> 
#> $a5
#> [1] 5
#> 
#> $a6
#> [1] 6
#> 
#> $a7
#> [1] 7
#> 
#> $a8
#> [1] 8
#> 
#> $a9
#> [1] 9
#> 
#> $a10
#> [1] 10
#> 
#> $b
#> [1] "Hello, World!"
#> 
#> $c
#> function (x, base = exp(1))  .Primitive("log")
#> 
#> $d.a
#> [1] 1
#> 
#> $d.b
#> [1] "z"