Context: R has two types of vector
Atomic vectors contain values
These values are all of the same type.
They are arranged contiguously.
Atomic vectors cannot contain objects.
There are six types of atomic vector: raw, logical, integer, numeic, complex and character.
Recursive vectors contain objects
R has two types of recursive vector: : list, expression.
Lists
- At top level: 1-dim indexed object that contains objects (not values)
- Indexed from 1 to length(list)
- Contents can be of different types
- Lists can contain the NULL object
- Deeply nested listed of lists possible
- Can be arbitrarily extended (not fixed)
List creation: usually using list()
> l1 <- list('cat', 5, 1:10, FALSE);l1
[[1]]
[1] "cat"
[[2]]
[1] 5
[[3]]
[1] 1 2 3 4 5 6 7 8 9 10
[[4]]
[1] FALSE
> l2 <- list ( x='dog', y=5+2i, z=3:8 );l2
$x
[1] "dog"
$y
[1] 5+2i
$z
[1] 3 4 5 6 7 8
> l3 <- c(l1, l2);l3
[[1]]
[1] "cat"
[[2]]
[1] 5
[[3]]
[1] 1 2 3 4 5 6 7 8 9 10
[[4]]
[1] FALSE
$x
[1] "dog"
$y
[1] 5+2i
$z
[1] 3 4 5 6 7 8
> l4 <- list(l1, l2);l4
[[1]]
[[1]][[1]]
[1] "cat"
[[1]][[2]]
[1] 5
[[1]][[3]]
[1] 1 2 3 4 5 6 7 8 9 10
[[1]][[4]]
[1] FALSE
[[2]]
[[2]]$x
[1] "dog"
[[2]]$y
[1] 5+2i
[[2]]$z
[1] 3 4 5 6 7 8
> l5 <- as.list( c(1,2,3));l5
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] 3
> origL <- l4
> inserVorL <- l5
> position <- 3
> l6 <- append(origL, inserVorL, position);l6
[[1]]
[[1]][[1]]
[1] "cat"
[[1]][[2]]
[1] 5
[[1]][[3]]
[1] 1 2 3 4 5 6 7 8 9 10
[[1]][[4]]
[1] FALSE
[[2]]
[[2]]$x
[1] "dog"
[[2]]$y
[1] 5+2i
[[2]]$z
[1] 3 4 5 6 7 8
[[3]]
[1] 1
[[4]]
[1] 2
[[5]]
[1] 3
Basic information about lists
> dim(l)
NULL
> is.list(l)
[1] TRUE
> is.vector(l)
[1] TRUE
> is.recursive(l)
[1] TRUE
> is.atomic(l)
[1] FALSE
> is.factor(l)
[1] FALSE
> length(l)
[1] 5
> names(l)
NULL
> mode(l)
[1] "list"
> class(l)
[1] "list"
> typeof(l)
[1] "list"
> attributes(l)
NULL
The contents of a list
> print(l)
[[1]]
[[1]][[1]]
[1] "cat"
[[1]][[2]]
[1] 5
[[1]][[3]]
[1] 1 2 3 4 5 6 7 8 9 10
[[1]][[4]]
[1] FALSE
[[2]]
[[2]]$x
[1] "dog"
[[2]]$y
[1] 5+2i
[[2]]$z
[1] 3 4 5 6 7 8
[[3]]
[1] 1
[[4]]
[1] 2
[[5]]
[1] 3
> str(l)
List of 5
$ :List of 4
..$ : chr "cat"
..$ : num 5
..$ : int [1:10] 1 2 3 4 5 6 7 8 9 10
..$ : logi FALSE
$ :List of 3
..$ x: chr "dog"
..$ y: cplx 5+2i
..$ z: int [1:6] 3 4 5 6 7 8
$ : num 1
$ : num 2
$ : num 3
> dput(l)
list(list("cat", 5, 1:10, FALSE), structure(list(x = "dog", y = 5+2i,
z = 3:8), .Names = c("x", "y", "z")), 1, 2, 3)
> head(l)
[[1]]
[[1]][[1]]
[1] "cat"
[[1]][[2]]
[1] 5
[[1]][[3]]
[1] 1 2 3 4 5 6 7 8 9 10
[[1]][[4]]
[1] FALSE
[[2]]
[[2]]$x
[1] "dog"
[[2]]$y
[1] 5+2i
[[2]]$z
[1] 3 4 5 6 7 8
[[3]]
[1] 1
[[4]]
[1] 2
[[5]]
[1] 3
> tail(l)
[[1]]
[[1]][[1]]
[1] "cat"
[[1]][[2]]
[1] 5
[[1]][[3]]
[1] 1 2 3 4 5 6 7 8 9 10
[[1]][[4]]
[1] FALSE
[[2]]
[[2]]$x
[1] "dog"
[[2]]$y
[1] 5+2i
[[2]]$z
[1] 3 4 5 6 7 8
[[3]]
[1] 1
[[4]]
[1] 2
[[5]]
[1] 3
Trap: cat(x) does not work with lists
Indexing [ versus [[ versus $
- Use [ to get/set multiple items at once
Note: [ always returns a list
- Use [[ and $ to get/set a specific item
- $ only works with named list items
all same: $name $"name" $'name' $`name`
- indexed by positive numbers: these ones
- indexed by negative numbers: not these
- indexed by logical atomic vector: in/out
an empty index l[] returns the list
Tip: When using lists, most of the time you wnat ot index with [[ or $; and avoid [
Indexing examples: one-dimension get
> j <- list(a='cat', b=5, c=FALSE)
> x <- j$a;x
[1] "cat"
> x <- j[['a']];x
[1] "cat"
> x <- j['a'];x
$a
[1] "cat"
> x <- j[[1]];x
[1] "cat"
> x <- j[1];x
$a
[1] "cat"
Indexing examples: set operations
- Start with example data
l <- list(x='a', y='b', z='c', t='d')
- Next use [[ or $ because specific selection
> l[[6]] <- 'new';
> names(l)[5] <- 'w'
> l$w <- 'new-W'
> l[['w']] <- 'dog'
- Change named values: note order ignored
> l[names(l) %in% c('t', 'x')] <- c(1,2)
> l
$x
[1] 1
$y
[1] "b"
$z
[1] "c"
$t
[1] 2
$w
[1] "dog"
[[6]]
[1] "new"
Indexing example: multi-dimension get
- Indexing evaluated from left to right
- Let's start with some example data...
> i <- c('aa', 'bb', 'cc')
> j <- list(a='cat', b=5, c=FALSE)
> k <- list(i, j);k
[[1]]
[1] "aa" "bb" "cc"
[[2]]
[[2]]$a
[1] "cat"
[[2]]$b
[1] 5
[[2]]$c
[1] FALSE
> k[[1]]
[1] "aa" "bb" "cc"
> k[[2]]
$a
[1] "cat"
$b
[1] 5
$c
[1] FALSE
> k[1]
[[1]]
[1] "aa" "bb" "cc"
> k[2]
[[1]]
[[1]]$a
[1] "cat"
[[1]]$b
[1] 5
[[1]]$c
[1] FALSE
> x <- k[[1]][[1]];x
[1] "aa"
> x <- k[[1]][[2]];x
[1] "bb"
> x <- k[1][1][1][1][1];x
[[1]]
[1] "aa" "bb" "cc"
> x <- k[1][2];x
[[1]]
NULL
> x <- k[[2]][1];x
$a
[1] "cat"
List manipulation
1 Arithmetic operators cannot be applied to lists (as content types can vary)
2 Use the apply() functions to apply a function of each element in a list:
> x <- list(a=1, b=month.abb, c=letters)
> lapply(x, FUN=length)
$a
[1] 1
$b
[1] 12
$c
[1] 26
> sapply(x, FUN=length)
a b c
1 12 26
y <- list(a=1, b=3, c=3, c=4)
sapply(y, FUN=function=(x,p) x^p, p=2)
sapply(y, FUN=function=(x,p) x^p, p=2:3)
3 Use unlist to convert list ot vector
> unlist(x)
a b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 c1 c2 c3 c4 c5 c6 c7
"1" "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec" "a" "b" "c" "d" "e" "f" "g"
c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26
"h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
unlist wont unlist non-atomic
4 Remove NULL objects from a list
> z <- list(a=1:9, b=letters, c=NULL)
> zNoNull <- Filter(Negate(is.null), z)
> zNoNull
$a
[1] 1 2 3 4 5 6 7 8 9
$b
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
5 Use named lists to return multiple values
6 Factor index treated as integer
decode with v[as.character(f)]
No comments:
Post a Comment