1、操作矩阵的行和列
*apply系列函数:
apply():apply(m,dimcode,f,fargs)
参数详解: m矩阵
矩阵维度编号 1代表行 2代表列
f 函数
fargs 函数f的可选参数集
exp:
z<-matrix(c(1,2,3,4,5,6),nrow=3)
apply(z,2,mean) #对矩阵z的列调用mean函数 替代函数colMeans() colMeans(z)
输出:
2 5 #第一列1 2 3平均2 第二列4 5 6平均5
exp:自定义f
z<-matrix(c(1,2,3,4,5,6),nrow=3)
f <- function(x){
x/c(2,8)
}
y <- apply(z,1,f)
输出:
0.5 1.000 1.50
0.5 0.625 0.75
apply()函数默认返回的行数为f函数返回的元素长度 所以上例中f返回两个元素 apply输出两行 如果f返回一个标量 则apply()返回一个向量
转置函数:t()
t(apply(z,1,f))
输出:
0.5 0.500
1.0 0.625
1.5 0.750
exp:函数参数fargs示例
x <- matrix(c(1,0,1,1,0,1,1,1,1,0,1,0,0,1,1,0,1,1,1,0),nrow=4)
copymaj <- function(rw d){
maj <- sum(rw[1:d])/d
return(if(maj > 0.5) 1 else 0)
}
apply(x,1,copymaj,3) #输出 1 1 0 1
apply(x,1,copymaj,2) #输出 0 1 0 0
案例:检测异常值(离散点)
findols <- function(xrow){
findol <- function(xrow){
mdn <- median(xrow) #median()中间距离
devs <- abs(xrow-mdn) #离散值
return(which.max(devs)) #最大离散值的位置(索引)
}
return(apply(x,1,findol)) #返回各行该异常值(最远的散点)
}
findols(rs)
tapply():分组统计(后叙)
lapply():返回list(后叙)
2、矩阵行列的增加删除
严格来讲矩阵不可以增加或者删除行列 只是通过重新赋值来改变矩阵的值 达到类似新增或删除的效果
rbind():按行绑定
cbind():按列绑定
与向量值得增加删除类似:
exp:
one <- c(1,1,1,1)
z <- matrix(c(1,2,3,4,1,1,,0,0,1,0,1,0),4)
cbind(one,z) #也可以利用循环补齐规则 改写为cbind(1,z)
输出:
1 1 1 1
1 2 1 0
1 3 0 1
1 4 0 0
案例:找到图中距离最近的一对端点
Code:
mind <- function(d){
n <- nrow(d) #行数
dd < - cbind(d,1:n) #按列绑定 相当于加行“序号”
wmins <- apply(dd[-n],1,imin) #除最后一行外 对每行使用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]
j <- which.min(x[(i+1):(lx-1)]) #最小值所在的位置
k <- i+j
return(c(k,x[k]))
}
代码现在不必深究 理解解题的思路以及部分函数的使用即可
3、向量与矩阵差异
矩阵类 exp:class(z) 输出“matrix” ;attributes(z) $dim 输出矩阵行数 列数
4、其它
避免降维:z[2,,drop=FALSE]
向量转矩阵:as.matrix(c)
矩阵列命名:colnames(z) <- c("a","b") 为矩阵z的第一列命名a 第二列命名b
矩阵行命名:rownames(z) <- c("A","B") 为矩阵z的第一行命名A 第二行命名B
多维数组:多于二维的数据使用数组表示(后续章节的列表、数据框等类型更容易表达此类数据)
exp:
tests <- array(data=c(test1,test2),dim=c(3,2,2)) #test1、test2均为矩阵 dim的c(3,2,2) 最后一个2表示两层; 前面的3,2每层3列两行。
取值:exp:tests[3,2,1] 表示第1层数据的第2列的第3行