Objects and their elements
Some (not all) R objects that we use will have a hierarchical structure in which elements or components of the object are located. For examples, data frames will contain the names and values of particular variables, and some results of function operations will contain values for model fit, parameter estimates, etc. nested within an overall model object. Accessing elements or attributes of an object depends on the nature of the object, and sometimes involves invoking functions referenced by the object. A couple of examples will illustrate (we will see later how to create these objects, for now just assume they exist):
Ex1- Data frame object containing radio telemetry data on Wild Turkeys over 3 years.
Ex2- Results of running a series of RMark models on the above data
Lists and arrays
An array is a dimensioned object that can contain numerical,character, or logical values. Actually, lists, whidh we have already seen, are also a type of dimensioned object, e.g.,
> a<-c(4,5,67)
> a
[1] 4 5 67
in which a contains 3 numerical elements (4, 5 and 67). A matrix is a 2-dimensional array. Both arrays and matrices will arise frequently in our analyses and have many uses.
Matrices and arrays can be created from other objects. For example, a 3 X 3 matrix can be specified by inputting into the matrix function an ordered list of values and specifiying the number of matrix rows. By default the elements are assigned to each column in order:
> #matrix
> x<-1:9Note
> x<-matrix(x,nrow=3)
> x
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
>
To assign by rows, the option byrow=T is specified
> x<-matrix(x,nrow=3,byrow=T)
> x
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
>
The entries can be logical values, for example
> y<-1:9>4
> y<-matrix(y,nrow=3,byrow=T)
> y
[,1] [,2] [,3]
[1,] FALSE FALSE FALSE
[2,] FALSE TRUE TRUE
[3,] TRUE TRUE TRUE
>
Entries can also be character values, for example
> z<-rep(c("a","b","c"),3)
> z<-matrix(z,nrow=3,byrow=T)
> z
[,1] [,2] [,3]
[1,] "a" "b" "c"
[2,] "a" "b" "c"
[3,] "a" "b" "c"
The elements of a matrix are reference by row and column. For example in the matrix
> x
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
the element in row 2 column 1 is gotten by
> x[2,1]
[1] 4
>
Individual elements can be reassigned value. For example
> x[2,1]<-6
changes the matrix to
> x
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 6 5 6
[3,] 7 8 9
>
Arrays generalize matrices to multiple dimensions and are created by the function
>array(x,dim)
where x is a list of values and dim is an list specifying dimensions. For example
> #vector placed in order by columns
> x<-1:27
> x<-array(x,dim=c(3,3,3))
creates a 3 X 3 X 3 array whose elements will be assigned from the sequence 1:27 by the innermost dimension first (analogous to the default for matrix). We will see later how programs can be written to more specifically reference array elements.
> x
, , 1
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
, , 2
[,1] [,2] [,3]
[1,] 10 13 16
[2,] 11 14 17
[3,] 12 15 18
, , 3
[,1] [,2] [,3]
[1,] 19 22 25
[2,] 20 23 26
[3,] 21 24 27
Leaving off the input vector results in an array of missing values, e.g,
> #empty array
> x<-array(dim=c(3,3,3))
> x
, , 1
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
[3,] NA NA NA
, , 2
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
[3,] NA NA NA
, , 3
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
[3,] NA NA NA
As another example, we can create an array whose values are random numbers, e.g.,
> #random elements
> x<-runif(27,1,10)
> x<-array(x,dim=c(3,3,3))
>
> #or
> x<-array(runif(27,1,10),dim=c(3,3,3))
If input of smaller dimension than the total number of elements is specified, the array function recycles the input list to fill the array:
> x<-1:3
> x<-array(x,dim=c(3,3,3))
> x
, , 1
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 2
[3,] 3 3 3
, , 2
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 2
[3,] 3 3 3
, , 3
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 2
[3,] 3 3 3
As with matrices, individual elements can be referenced and reassigned, e.g.,
> # get an element of x
> x[3,3,1]
[1] 3
>
> #re-assign a value to element
> x[3,3,1]=0
> x
, , 1
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 2
[3,] 3 3 0
, , 2
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 2
[3,] 3 3 3
, , 3
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 2
[3,] 3 3 3
Finally, attempts to exceed the dimensions of an array will produce an error, for example
> #index error
> x[4,3,1]
Error in x[4, 3, 1] : subscript out of bounds
>
Note that various objects in R can be forces (or "coerced") to matrices or arrays. Recall the dataframe
> obs
temperature humidity
1 20 100
2 25 70
3 19 60
4 21 NA
5 24 80
This is coerced into a matrix by
> xx<-as.matrix(obs)
> xx
temperature humidity
[1,] 20 100
[2,] 25 70
[3,] 19 60
[4,] 21 NA
[5,] 24 80
>
The coercion can work in the other direction
> as.data.frame(xx)
temperature humidity
1 20 100
2 25 70
3 19 60
4 21 NA
5 24 80
>
Although these objects look very similar, it is important to realize that R treats them differently, and some operations will work on one or the other but not both formats.
A final, fairly useful function is apply, which is used to apply the operation of some other function (like sum or mean) to the margins (a selected dimension) of a matrix or array. To illustrate, we'll use apply to get row and column totals for the xx matrix above
> #row totals
> apply(xx,1,sum)
[1] 120 95 79 NA 104
> #column totals
> apply(xx,2,sum)
temperature humidity
109 NA
>
The above results illustrate a common problem in applying operations like sum and mean: if any values are missing the result will be NA. A solution is provided by the na.rm option, which removes missing values and computes the desired function. E.g.,
> #column means, missing removed
> apply(xx,2,mean,na.rm=T)
temperature humidity
21.8 77.5
>