R语言NGS

R语言编程艺术 第3章 矩阵

2019-04-05  本文已影响98人  小洁忘了怎么分身

矩阵是一种特殊的向量,包括两个附加的属性:行数和列数。所以矩阵和向量一样,有数据类型的概念。

数组是高维的对象,矩阵是数组的特殊情形。 ###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
上一篇下一篇

猜你喜欢

热点阅读