16.3 Matrix Manipulation

Once a matrix or an array has been defined it might be necessary to either extract some submatrices from the matrix, to reshape it, i.e. change its dimensions, or to modify the order of its elements. You find all the following examples in 36813 XLGmatrix04.xpl and 36816 XLGmatrix05.xpl .


16.3.1 Extraction of Elements


y = x[i,j] or y = x[i,] or y = x[,j]
extracts element i,j or row i or column j from x
y = 36984 index (x, ind)
generates a new matrix y from an old matrix x by extracting the rows of x indicated in the index vector ind
y = 36987 paf (x, ind)
selects rows of an object x depending on a given vector ind resulting in the matrix y
y = 36990 sort (x, c)
sorts the rows of a matrix x by the vector c

We extract elements or submatrices of a matrix with the operator []. Consider the $ 4\times 3$ matrix

  mat=(1|2|3|4)~(5|6|7|8)~(9|9|9|9)
The following three lines extract respectively the first row, the second column, and the element in the fourth row and third column:
  mat[1,]                  ; extract first row
  mat[,2]                  ; extract second column
  mat[4,3]                 ; extract element (4,3)

The [] operator can be combined with the range operator, denoted by the colon symbol :, and the $ \vert$ operator. The command

  mat[1:3,1|3]
extracts the elements which are between the first and the third rows of mat and in the 1st and 3rd columns.

In a similar way, we extract certain rows from a matrix with the function 36997 index . Its first argument is the matrix, its second argument is the index of the considered rows. This second argument can be a vector of indices. In that case, all rows which are in the index vector are extracted. The instructions

  x = #(1,3,5)~#(2,4,6)
  index (x,#(3,2))
create a $ 3\times 2$ matrix, and respectively extract its third and second rows:
  Contents of index
  [1,]        5        6
  [2,]        3        4
Note that index(x,#(3,2)) is identical to x[#(3,2)] as long as the values in the index vector -- here #(3,2) -- do not exceed the dimension of x. If this is the case, x[#(3,2)] would return an error message while the 37000 index function returns NaN values.

We can select rows of a matrix on the basis of a logical condition with the function 37003 paf . The first argument of the function is the matrix, the second argument is an indicator vector with the same row dimension as the matrix. The function 37006 paf selects the rows of the matrix whose corresponding element in the indicator vector is different from zero. Note that 37009 paf returns an error, if no element of the indicator vector is different from zero!

The following example illustrates the use of this function:

  x = #(4, 2, 5)
  ind = x > 3
  paf(x, ind)
The three-dimensional vector x and the three-dimensional indicator vector ind are created. Since the vector ind is created with the logical condition x > 3, its elements are either equal to 1 if the corresponding element of the vector x is strictly greater than 3, or to zero otherwise. As only the second element of x is less than 3, the second element of ind is set to zero, the function 37012 paf selects the remaining first and third rows of x and returns them:
  Contents of paf
  [1,]        4 
  [2,]        5

The function 37015 sort sorts the rows of a matrix. Its first argument is the matrix, its second argument is the column with respect to which the sorting is done. If this column order is positive, the matrix will be sorted by that column in ascending order, while if the column order is negative, the matrix will be sorted in descending order. The column order can be a vector. In that case, the matrix is first sorted by the first element of the sorting vector, next the matrix is sorted by the second element of the sorting vector provided that this second sorting does not modify the previous one. The instructions

  x = #(4,2,5)~#(1,7,4)
  x
  sort(x,-2)
create a $ 3\times 2$ matrix. Since the second argument of 37018 sort is equal to -2, this matrix is sorted in descending order by the second column:
  Contents of x
  [1,]        4        1 
  [2,]        2        7 
  [3,]        5        4 
  Contents of sort
  [1,]        2        7 
  [2,]        5        4 
  [3,]        4        1
If the second argument of the function 37021 sort is set to 0, all columns of the matrix are independently sorted in ascending order. This means,
  sort(x,0)
gives
  Contents of sort
  [1,]        2        1 
  [2,]        4        4 
  [3,]        5        7

Let us remark that all functions from this section can also be applied to alphanumeric matrices. Also, the extension to higher-dimensional arrays is straightforward.


16.3.2 Matrix Transformation


y = 37230 reduce (x)
deletes all dimensions of x with only a single component
y = 37233 reshape (x, d)
transforms an array x into a new one y with given dimensions d
y = 37236 vec (x1 {,x2 ...})
vectorizes the arrays x1, x2, ...

If some of the dimensions of a multidimensional matrix are equal to one, we can discard them with the function 37239 reduce . Since this function is part of the library xplore , this library should be loaded before the use of the function. The commands

  library("xplore")
  x = matrix(3,1,2,1)
  reduce(x)
create a $ 3\times 1\times 2 \times 1$ matrix of ones, discard the two dimensions equal to one, and leave a $ 3\times 2$ matrix which is displayed as follows:
  Contents of y
  [1,]        1        1 
  [2,]        1        1 
  [3,]        1        1

The dimensions of an array can be modified with the function 37244 reshape although the modified array does contain the same number of elements as the original array. The first argument of the function is the array to be modified, i.e. the source array, the second argument is the dimension of the target array. The function 37247 reshape reads rowwise the elements of the source array and stores them rowwise into the target array. The commands

  x = #(1, 1, 1, 1, 1)~#(2, 2, 2, 2, 2)
  x
  d = #(2, 5)   
  reshape(x, d)
create a $ 5\times 2$ matrix, display it, reshape it into a $ 2\times 5$ matrix, and display it:
  Contents of x
  [1,]        1        2
  [2,]        1        2
  [3,]        1        2
  [4,]        1        2
  [5,]        1        2
  Contents of reshape
  [1,]        1        1        1        2        2
  [2,]        1        1        2        2        2

The function 37250 vec reshapes a matrix into a vector:

  vec(x)
yields
  Contents of #
  [ 1,]        1 
  [ 2,]        1 
  [ 3,]        1 
  [ 4,]        1 
  [ 5,]        1 
  [ 6,]        2 
  [ 7,]        2 
  [ 8,]        2 
  [ 9,]        2 
  [10,]        2
The 37253 vec function can optionally add some elements to the reshaped vector:
  vec(x,5)~vec(3,x)
returns
  Contents of _tmp
  [ 1,]        1        3 
  [ 2,]        1        1 
  [ 3,]        1        1 
  [ 4,]        1        1 
  [ 5,]        1        1 
  [ 6,]        2        1 
  [ 7,]        2        2 
  [ 8,]        2        2 
  [ 9,]        2        2 
  [10,]        2        2 
  [11,]        5        2
The instruction vec(x,5) reshapes the matrix x into a vector and adds the number 5 as the last element of the created vector. However, since the number 3 is the first argument of the function 37256 vec in the instruction vec(3,x), the first element of the created vector is this number to which the ``vectorized'' matrix is added.

As a consequence, both instructions

  z1 = #(1,2,3)
  z2 = vec(1,2,3)
are equivalent.