R语言初级教程(13): 矩阵(上篇)

R语言初级教程(13): 矩阵(上篇)

R中有5种基本数据结构,分别是向量(vector)、矩阵(matrix)、数组(array)、数据框(data frame)和列表(list)。它们的结构如下图:


R中的数据结构


其中向量、矩阵和数组中的数据类型必须是相同的;而数据框和列表中的数据类型可以是不一样的。

其中的向量已经介绍过了,向量是一维数组,详情见初级教程09, 10和11。

接下来的一些博客将介绍其它4种数据结构。

首先介绍矩阵,矩阵是一个二维数组。这篇博客将主要介绍矩阵的创建元素的访问以及元素的修改

1. 创建矩阵

在R中,使用matrix()函数来创建矩阵是最常用的方式。matrix()的原型为:matrix(data=NA, nrow=1, ncol = 1, byrow=FALSE, dimnames=NULL),其中参数的意义分别为:

  • data:包含了矩阵的元素,一般是个向量,默认情况下是NA
  • nrowncol:设定矩阵的行、列数目;一般这两个值只需设定一个,另外一个值可根据元素个数自动给出
  • byrow:设定矩阵是按行(byrow=TRUE)填充还是按 列(byrow=FALSE)填充,默认情况下按列填充
  • dimnames:包含了以字符型向量表示的行名和列名,是一个列表,默认情况下没有行列名

来看些例子:

> mat1 <- matrix(1:6, nrow=2)   ##默认按列填充
> mat1
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

> mat2 <- matrix(1:6, nrow=2, byrow=TRUE)   ##设定byrow=TRUE按行填充
> mat2
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6

> rnames <- c('R1', 'R2')   ##行名
> cnames <- c('C1', 'C2', 'C3')  ##列名
> mat3 <- matrix(1:6, nrow=2, dimnames=list(rnames, cnames))   ##通过设定dimnames参数添加行列名
> mat3
   C1 C2 C3
R1  1  3  5
R2  2  4  6

###也可通过使用rownames()、colnames()函数来给矩阵添加行、列名
> rownames(mat) <- c('r1', 'r2')    ##添加行名
> colnames(mat) <- c('c1', 'c2', 'c3')   ##添加列名
> mat
   c1 c2 c3
r1  1  2  3
r2  4  5  6
也可通过使用rownames()colnames()函数来给矩阵添加行、列名

此外,也可通过使用dim()函数来创建矩阵,其原理是通过改变维度使向量变为矩阵。比如:

> mat4 <- 1:6   ##向量
> dim(mat4) <- c(3, 2)  ##变为3行2列的矩阵
> is.matrix(mat4)   ##判断是否为矩阵
[1] TRUE
> mat4      ##默认按列填充
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

如何将上面例子变为按行填充呢?可结合矩阵转置函数t()来实现,来看个例子:

> mat4 <- 1:6
> dim(mat4) <- c(2, 3)   ##与上面不一样
> mat4 <- t(mat4)   ##矩阵转置
> mat4   ##按行填充
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6

2. 矩阵的属性

直接来看个例子:

> mat <- matrix(1:6, nrow=2, dimnames=list(rnames, cnames)) 
> mat
   C1 C2 C3
R1  1  3  5
R2  2  4  6
> class(mat)  ##结构类型
[1] "matrix"
> typeof(mat)  ##元素数据类型
[1] "integer"
> dim(mat)  ##维度,2行3列
[1] 2 3
> length(mat)  ##元素个数
[1] 6
> rownames(mat)  ##获取行名
[1] "R1" "R2"
> colnames(mat)  ##获取列名
[1] "C1" "C2" "C3"

3. 访问矩阵中的元素

类似于向量元素的访问,只是增加了一个维度而已。来看一些例子:

> mat <- matrix(1:9, nrow=3, dimnames=list(c('r1', 'r2', 'r3'), c('c1', 'c2', 'c3'))) 
> mat
   c1 c2 c3
r1  1  4  7
r2  2  5  8
r3  3  6  9
> mat[2, 2]  ##访问第2行第2列元素
[1] 5
> mat[2, ]  ##访问第2行元素
c1 c2 c3 
 2  5  8 
> is.vector(mat[2, ])  ##返回为向量
[1] TRUE
> mat[, 2]  ##访问第2列元素
r1 r2 r3 
 4  5  6 
> mat[c(2, 3), c(2, 3)]  ##访问第2、3行第2、3列元素,返回为矩阵
   c2 c3
r2  5  8
r3  6  9

### 也可通过行、列名来访问元素
> mat['r2', 'c2']
[1] 5
> mat['r2', ]
c1 c2 c3 
 2  5  8 
> mat[c('r2','r3'), c('c2','c3')]
   c2 c3
r2  5  8
r3  6  9

值得注意的是,当用上面的方式获取某个或某行或某列元素时,返回的是一个向量。如何使返回值也为矩阵呢?来看个例子:

> mat[2, 2, drop=FALSE]
   c2
r2  5
> mat[2, , drop=FALSE]
   c1 c2 c3
r2  2  5  8

> is.matrix(mat[2, 2, drop=FALSE])   ##返回的是个矩阵
[1] TRUE
> is.matrix(mat[2, , drop=FALSE])   ##返回的是个矩阵
[1] TRUE
通过将参数drop设定为FALSE,返回的将会是个矩阵

4. 修改矩阵中的元素

类似于向量,我们可以通过赋值运算来改变矩阵中的内容,比如:

> mat <- matrix(1:9, nrow=3) 
> mat
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

> mat[2, 2] <- 20   ##将第2行第2列元素改为20
> mat
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2   20    8
[3,]    3    6    9

> mat[ ,3] <- 10   ##将第3列元素都改为10
> mat
     [,1] [,2] [,3]
[1,]    1    4   10
[2,]    2   20   10
[3,]    3    6   10

> mat[mat<6] <- 7   ##将小于6的元素都改为7
> mat
     [,1] [,2] [,3]
[1,]    7    7   10
[2,]    7   20   10
[3,]    7    6   10

> mat <- mat[-2, ]   ##删掉第二行
> mat
     [,1] [,2] [,3]
[1,]    7    7   10
[2,]    7    6   10

另外,通过rbind()cbind()函数可添加行和列,来看个例子:

> mat <- matrix(1:9, nrow=3) 
> mat
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

> rbind(mat, c(12, 13, 14))   ##在原矩阵mat后面添加一行
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
[4,]   12   13   14

> cbind(mat, c(12, 13, 14))   ##在原矩阵mat后面添加一列
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   12
[2,]    2    5    8   13
[3,]    3    6    9   14

R矩阵的第一部分内容:矩阵的创建元素的访问以及元素的修改就讲到这。

如若有遗漏,后期将会添加至本博客。


感谢您的阅读!想了解更多有关R语言技巧,请关注我的微信公众号“R语言和Python学堂”,我将定期更新相关文章。


weixin.qq.com/r/HBxWTiH (二维码自动识别)

发布于 2018-10-20 18:00