R-006 matrix trong R

Nội dung bài viết

matrix là một những kiểu dữ liệu cơ bản của R.

Để hiểu rõ matrix của R các bạn có thể đọc tài liệu chi tiết về matrix bằng lệnh:

?matrix

1. Tạo một ma trận matrix:

Ma trận trong R có thể tạo với hàm matrix().

Chiều của ma trận có thể tự “suy diễn” bởi giá trị nrowncol truyền vào, việc truyền cả hai tham số vào đôi khi không cần thiết. Ví dụ sử dụng nrow:

m1 <- matrix(1:6, nrow=3)
m1
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

Hay sử dụng ncol:

m2 <- matrix(1:6, ncol=3)
m2
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

Một điều nếu bạn quan sát kĩ sẽ thấy, R khi dùng hàm matrix nó tự động lấy các giá trị của vector và phủ theo cột (từ trên xuống). Nếu bạn muốn phủ theo hàng thì cần sửa tham số mặc đinh byrow=FALSE về thành TRUE. Ở đây mình sẽ ví dụ cả hai trường hợp cùng lúc cho bạn đọc dể quan sát:

# Trường hợp mặc định byrow = FALSE (không cần khai báo gì thêm)
m3 <- matrix(1:6, nrow=3)
m3
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6
# Trường hợp byrow = TRUE lúc này matrix sẻ phủ theo dòng
m4 <- matrix(1:6, nrow=3, byrow=TRUE)
m4
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6

Một cách khác nữa để tạo ma trận là sử dụng hàm cbind() và hàm rbind() dùng để tạo các ma trận từ các vector cột hoặc vector hàng:

a.vec <- c(1, 1, 1)
b.vec <- c(2, 2, 2)
c.vec <- c(3, 3, 3)
cbind(a.vec, b.vec, c.vec)
     a.vec b.vec c.vec
[1,] "a"   "b"   "c"  
[2,] "a"   "b"   "c"  
[3,] "a"   "b"   "c"

Tương tự với hàm rbind() bạn đọc tự kiểm tra.

Lưu ý là matrix trong R cho phép đặt tên cho hàng và cột, như kết quả thu được ở trên, các cột tạo bởi hàm cbind tự động đặt tên là a.vec, b.vec, c.vec. Tuy nhiên đối với mình thì đây là một chức năng không cần thiết, nếu bạn đọc muốn tìm hiểu thêm có thể tìm hiểu hàm colnames()rownames() trong R để thực hiện việc này.

2. Xem chiều của một matrix:

Để xem chiều của một matrix trong R chúng ta có thể sử dụng hàm dim().

Giá trị đầu tiên trả về là số dòng nrow, giá trị tiếp theo là số cột ncol.

dim(m1)
[1] 3 2

3. Trích phần tử từ matrix:

Để trích các phần tử từ ma trận chúng ta có thể sử dụng toán tử [vec.dim.m, vec.dim.n]. Ở đây mình lưu ý rằng mỗi chiều có thể lấy theo chỉ số index đánh thứ tự, nếu bỏ trống mặc định sẽ lấy hết toàn bộ:

  • Lấy vector cột
# Lấy vector cột của m1
m1[,2]
[1] 4 5 6
  • Lấy vector dòng
# Lấy vector dòng của m1
m1[3,]
[1] 3 6
  • Lấy theo vector với dãy index:
# Lấy vector cột của m1
m1[c(1,3), ]
     [,1] [,2]
[1,]    1    4
[2,]    3    6

4. Kiểm tra đối tượng có phải là matrix

Để kiểm tra một đối tượng có phải là matrix hay không, các bạn có thể dùng hàm is.matrix.

d <- warpbreaks # Dataframe từ dữ liệu warpbreaks
str(d) # in ra thông tin đối tượng
is.matrix(d) # Kiểm tra xem đối tượng có phải là một matrix không 
'data.frame':  54 obs. of  3 variables:
 $ breaks : num  26 30 54 25 70 52 51 26 67 18 ...
 $ wool   : Factor w/ 2 levels "A","B": 1 1 1 1 1 1 1 1 1 1 ...
 $ tension: Factor w/ 3 levels "L","M","H": 1 1 1 1 1 1 1 1 1 2 ...
 [1] FALSE

5. Ép kiểu đối tượng thành matrix

Một trong những hàm hữu ích của matrix trong R là hàm as.matrix, hàm này cho phép ép một số đối tượng về ma trận.

matrix.warpbreaks <- as.matrix(d) # Ép kiểu của data.frame bước trên
is.matrix(matrix.warpbreaks)
[1] TRUE

Hoặc thậm chí có thể ép một vector về dạng matrix (n rows x 1 col) như sau:

col.vector <- as.matrix(1:6)
col.vector
     [,1]
[1,]    1
[2,]    2
[3,]    3
[4,]    4
[5,]    5
[6,]    6

6. Tính toán đại số với matrix:

Đây là những phép tính quan trọng :D đặc biệt là phép nhân, nếu các bạn nào chưa quen thì cần cẩn thận với phép nhân ma trận, xác định phép nhân mà mình đang định dùng:

Gọi mat.Amat.B là hai ma trận, vec.xvec.y là hai vector, k là một số nguyên.

Toán tử hoặc hàm Chú thích
mat.A * mat.B Nhân từng phần từ
mat.A %*% mat.B Nhân ma trận
t(mat.A) Ma trận chuyển vị
diag(vec.x) Tạo ma trận đường chéo từ vector
diag(mat.A) Lấy vector đường chéo từ ma trận
diag(k) Tạo một ma trận đơn vị k x k
solve(mat.A, vec.y) Trả về vector x nghiệm của hệ y = Ax
(với y là vec.y, và A là mat.A)
solve(mat.A) Lấy ma trận nghịch đảo của A
res <- eigen(mat.A) Lấy trị riêng vector riêng ma trận
- res$val là trị riêng của mat.A
- res$vec là vector riêng của mat.A
cbind(mat.A,mat.B,…) Kết hợp nhiều ma trận lại theo chiều ngang
rbind(mat.A,mat.B,…) Kết hợp nhiều ma trận lại theo chiều dọc
rowMeans(mat.A) Tính trung bình theo dòng
rowSums(mat.A) Tính tổng theo dòng
colMeans(mat.A) Tính trung bình theo cột
colSums(mat.A) Tính tổng theo cột
  • A*B (element-wise multiplication): phép nhân từng phần tử của hai ma trận cùng chiều.
mat1 <- matrix(1:6, nrow=2)
mat2 <- matrix(11:16, nrow=2)
mat1
mat2
mat1*mat2
# Kết quả ma trận 1
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
# Kết quả ma trận 2
     [,1] [,2] [,3]
[1,]   11   13   15
[2,]   12   14   16
# Kết quả nhân hai ma trận A*B
     [,1] [,2] [,3]
[1,]   11   39   75
[2,]   24   56   96
  • A %*% B (matrix multiplication): nhân ma trận đại số.
mat3 <- matrix(1:6, nrow=2)
mat4 <- matrix(2:4, nrow=3)
mat3 %*% mat4
     [,1]
[1,]   31
[2,]   40

Các phép toán và hàm còn lại bạn đọc tự kiểm tra. :D