矩阵是一种特殊的向量,包括两个附加的属性:行数和列数。所以矩阵和向量一样,有数据类型的概念。
数组是高维的对象,矩阵是数组的特殊情形。 ###3.1创建矩阵 按列存储,先第一列再第二列,以此类推。 matrix()函数
y <- matrix(c(1,2,3,4),nrow = 2,ncol = 2)
y
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
在矩阵中的四个元素都指定了的情况下,nrow和ncol二选一即可
y <- matrix(c(1,2,3,4),nrow = 2)
也可先列框架再挨个赋值
y=matrix(nrow = 2,ncol = 2)
y
## [,1] [,2]
## [1,] NA NA
## [2,] NA NA
y[1,1] <- 1
y[2,1] <- 2
y[1,2] <- 3
y[2,2] <- 3
参数:byrow=T,元素按行排列 ### 3.一般矩阵运算
3.1.线性代数运算
y %*% y
## [,1] [,2]
## [1,] 7 12
## [2,] 8 15
3*y
## [,1] [,2]
## [1,] 3 9
## [2,] 6 9
y+y
## [,1] [,2]
## [1,] 2 6
## [2,] 4 6
3.2 矩阵索引
提取子矩阵 例如:z[2:3,],y[c(1,3),] 可以给子矩阵赋值
y[c(1,2),] <- matrix(c(1,1,8,12),nrow = 2)
x <- matrix(nrow = 3,ncol = 3)
y <- matrix(c(4,5,2,3), nrow = 2)
y
## [,1] [,2]
## [1,] 4 2
## [2,] 5 3
x[2:3,2:3] <- y
负值表示反选、排除
y[-2,]表示去掉第二行
3.3 矩阵元素筛选
x <- matrix(c(1:3,2:4),nrow = 3)
x
## [,1] [,2]
## [1,] 1 2
## [2,] 2 3
## [3,] 3 4
j <- x[,2]>=3
j
## [1] FALSE TRUE TRUE
x[j,]
## [,1] [,2]
## [1,] 2 3
## [2,] 3 4
z <- c(5,12,13)
x[z%%2==1,]
## [,1] [,2]
## [1,] 1 2
## [2,] 3 4
x[x[,1]>1 & x[,2]>3,]
## [1] 3 4
which(x>2)
## [1] 3 5 6
假设n个随机变量的方差都为1,每两个变量之间的相关性都是rho,则生成协方差矩阵的函数
makecov <- function(rho,n) {
m <- matrix(nrow=n,ncol=n)
m <- ifelse(row(m) == col(m),1,rho)
return(m)
}
3.3 对矩阵的行和列的调用函数
apply()参数:
apply(X, MARGIN, FUN, ...)
X表示操作的数组/矩阵名称 MARGIN表示维度编号,1表示行,2表示列 FUN表示函数,如果函数有多个参数,以逗号分隔加在后面。
z <- matrix(c(1:3,4:6),nrow = 3)
z
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
apply(z, 2, mean)
## [1] 2 5
f <- function(x)x/c(2,8)
y <- apply(z,1,f)
y
## [,1] [,2] [,3]
## [1,] 0.5 1.000 1.50
## [2,] 0.5 0.625 0.75
由此可见,apply产生矩阵形式的结果时,是默认按列输出。
3.3.2 寻找异常值
findols <- function(x) {
findol <- function(xrow) {
mdn <- median(xrow)
devs <- abs(xrow-mdn)
return(which.max(devs))
}
return(apply(x,1,findol))
}
寻找每行的离群点(与中位数差值的绝对值最大的数)所在位置
3.4 增加或删除矩阵的行或列
3.4.1 改变矩阵的大小
cbind和rbind可以按行或列拼接矩阵
z
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
cbind(z,1)
## [,1] [,2] [,3]
## [1,] 1 4 1
## [2,] 2 5 1
## [3,] 3 6 1
重新赋值以删除行
z <- z[c(1,3),]
z
## [,1] [,2]
## [1,] 1 4
## [2,] 3 6
3.4.2 扩展案例:找到图中距离最近的一对的端点
方法一:
mind <- function(d) {
n <- nrow(d)
dd <- cbind(d,1:n)
wmins <- apply(dd[-n,],1,imin)
i <- which.min(wmins[2,])
j <- wmins[1,i]
return(c(d[i,j],i,j))
}
imin <- function(x) {
lx <- length(x)
i <- x[lx] # original row number
j <- which.min(x[(i+1):(lx-1)])
k <- i+j
return(c(k,x[k]))
}
imin函数返回了最小值和下标,wmins则是apply计算出的每行最小值及其下标矩阵,i和j是最小值的行列号。
方法二:
minda <- function(d) {
smallest <- min(d)
ij <- which(d == smallest,arr.ind=TRUE)
return(c(smallest,ij))
}
方法二不适用于有多个最小值的情况,但会简洁一些。
3.5 向量和矩阵的差异
矩阵比向量多两个属性:行数和列数
z <- matrix(1:8,nrow = 4)
z
## [,1] [,2]
## [1,] 1 5
## [2,] 2 6
## [3,] 3 7
## [4,] 4 8
length(z)
## [1] 8
class(z)
## [1] "matrix"
attributes(z)
## $dim
## [1] 4 2
attributes(z)$dim
## [1] 4 2
nrow 和ncol是对dim的简单封装
nrow <- function(x) dim(x)[1]
3.6 避免意外降维
按行/列取子集使矩阵变向量,也就是自动降维,避免降维的参数是drop
z
## [,1] [,2]
## [1,] 1 5
## [2,] 2 6
## [3,] 3 7
## [4,] 4 8
r=z[2,]
dim(r)
## NULL
r <- z[2,,drop=FALSE]
dim(r)
## [1] 1 2
3.7 矩阵的行和列命名
给colnames/rownames赋值
z
## [,1] [,2]
## [1,] 1 5
## [2,] 2 6
## [3,] 3 7
## [4,] 4 8
colnames(z) <- c("a","b")
rownames(z) <- LETTERS[1:4]
3.8 高维数组
三维是再行列的基础上增加"层"的属性
firsttest <- matrix(c(46,21,50,30,25,50),nrow = 2)
secondtest <- matrix(c(46,43,41,35,50,50),nrow = 2)
tests <- array(data = c(firsttest,secondtest),dim = c(3,2,2))
tests
## , , 1
##
## [,1] [,2]
## [1,] 46 30
## [2,] 21 25
## [3,] 50 50
##
## , , 2
##
## [,1] [,2]
## [1,] 46 35
## [2,] 43 50
## [3,] 41 50
attributes(tests)
## $dim
## [1] 3 2 2
#取子集
tests[3,2,1]
## [1] 50
网友评论