“ 矩阵是可以看作一种特殊的向量的,它比向量多了两个附加属性,行数和列数,因此让它的复杂程度获得了提高。 ”
向量作为R中的一种非常基础的数据类型,大家通过过去的学习一定已经彻底的掌握了。但是,这个世界上的数据是复杂多变的,我们只使用向量是无法表示更加复杂的数据情况。
我们在线性代数课上学过一种数学概念,矩阵。这个概念在为了统计学家开发的R语言中同样适用,并且只需要在基础环境中,我们可以具有很多对矩阵的 *** 作方法。
( 由于R其实处理数据框较多,矩阵并不会讲很多的东西,如果非要使用矩阵,我其实还是更推荐去隔壁Python学习np和scipy )
任何数据类型学习的开始都是如何得到它,也就是如何创建它。矩阵也不例外,我们首要的 创建方式就是直接使用matrix函数进行创建 。而且其实说是创建矩阵,我们其实是在把一个向量转化为矩阵,
上面就是最基本的创建矩阵的方法了。我们 需要给matrix一个向量 (其实矩阵也可以,不过就会让你产生一些奇奇怪怪的误导,后面讲解了矩阵转向量的时候你就明白了),这个向量的内容就会成为创建的矩阵的内容。
然后跟着需要 指定你想创建的行数或者列数 ,这两个只需要指定其一即可,R会给我们计算另一个数字是几的,这样,我们就创建好了一个矩阵。
但是我们可以发现一个问题,我们创 建的矩阵是竖着一排排放的,这个叫做,****列优先原则 ,我们也可以通过指定参数 byrow,来让矩阵变成行优先 的
这就是行优先矩阵了,存储的内容都是一样的,就是行列优先顺序不同。
到这里你可能就会问了,R是不是只能创建方阵呢,普通的矩阵能不能创建呢?那当然可以了
我本人是习惯列优先进行存储的,所以我一般不指定byrow参数。
任何一种数据类型,我们对它最优先的 *** 作学习,都是索引 *** 作。任何一种结构的数据,我们存储它的目的都是为了使用,所以学习如果取到它的值,是非常重要的事情。
对矩阵的基本索引方式和向量非常相似,如果不了解向量的直接索引,布尔索引和连续索引,请看
由于有了上面的基础,所以我们先索引点简单的,然后做两个不一样的案例。矩阵和向量最大的区别再与矩阵具有两个维度,索引的时候需要两个位置
这里停一下,我们取第一行的所有列就已经是不同了,要注意, 当我们想取某一行的所有列,或者某列的所有行,或者当你想取所有的时候,把位置空出来 ,R就会自动给你取到所有。
说完了上面的,下面就都非常简单了
大家尤其要注意最后一种,取前两行和后两列的 *** 作,很多时候这是非常有用的步骤,会减少你使用循环,提高程序的运行速度。
讲解完了索引,我们来讲一下如何矩阵的内容以及删除矩阵的行列。
其实修改特定位置的值非常简单,我们都已经找到了,修改就是一瞬间的事情,
除了单个值的修改,我们 还可以对索引到的行和列进行修改 ,一般来说,我们会直接把要修改的结果放进向量中,然后进行修改,但是如果修改的值不够长,也是可以 *** 作的,如下
如果你对上面的内容表示有些困惑,那么你应该回忆一下,
这里有着你需要了解的一切。
最后讲解如何删除矩阵的行列,这里的 *** 作也和向量是一样的,具体请回顾
本文的全部内容就到此结束了,这篇文章讲解了 最最基本的矩阵创建方法,以及对矩阵进行索引的 *** 作,加上修改矩阵元素和删除矩阵的列等等 ,这些都是使用矩阵的基础知识,需要彻底掌握,才能在矩阵的使用中得心应手。
下一篇文章将会介绍矩阵维度,矩阵转化为向量以及矩阵的各种运算,矩阵的转置等内容。
R语言的矩阵默认可以看成按列组成的向量,函数which可以判定那个位置上元素为不是零,根据位置判断其前后,以及前一列,后一列位置上的元素是不是为0,如当前是i,则前一个后一个分别为i-1,i+1,而前一列对应位置则为i-num.of.row-1,i-num.of.row,i-num.of.row+1,后一列i+num.of.row-1,i+num.of.row,i+num.of.row+1。特殊情况就是判断边界的时候进行出来,看我的例子:
m <- matrix(0,10,10)m[4,4] <-20
m[4,5] <-20
m[3,9] <-20
m[7,9] <-20
m
nr <- nrow(m)
nc <- ncol(m)
for(i in which(m!=0)){
#如果是第一列,不处理前列列
if(i<nr){
# 前一个 i-1,后一个i+1
# 下一列 i+nr-1,i+nr,i+nr+1
if(i%%nr==1){#如果是第一行
chs <- c(i+1,i+nr,i+nr+1)
for(j in chs){
if(m[j]==0){
m[j] <-1000
}
}
}
else if(i%%nr==0){#如果是最后一行
chs <- c(i-1,i+nr-1,i+nr)
for(j in chs){
if(m[j]==0){
m[j] <-1000
}
}
}else{
chs <- c(i-1,i+1,i+nr-1,i+nr,i+nr+1)
for(j in chs){
if(m[j]==0){
m[j] <-1000
}
}
} }
#如果是最后一列,不处理后一列
else if(i>nr*(nc-1)){
if(i%%nr==1){#如果是第一行
chs <- c(i-nr,i-nr+1,i+1)
for(j in chs){
if(m[j]==0){
m[j] <-1000
}
}
}
else if(i%%nr==0){#如果是最后一行
chs <- c(i-1,i-nr-1,i-nr)
for(j in chs){
if(m[j]==0){
m[j] <-1000
}
}
}else{
chs <- c(i-1,i+1,i-nr-1,i-nr,i-nr+1)
for(j in chs){
if(m[j]==0){
m[j] <-1000
}
}
}
}
#不是第一列也不是最后一列
else{
if(i%%nr==1){#如果是第一行
chs <- c(i-nr,i-nr+1,i+1,i+nr,i+nr+1)
for(j in chs){
if(m[j]==0){
m[j] <-1000
}
}
}
else if(i%%nr==0){#如果是最后一行
chs <- c(i-nr-1,i-nr,i-1,i+nr-1,i+nr)
for(j in chs){
if(m[j]==0){
m[j] <-1000
}
}
}else{
chs <- c(i-nr-1,i-nr,i-nr+1,i-1,i+1,i+nr-1,i+nr,i+nr+1)
for(j in chs){
if(m[j]==0){
m[j] <-1000
}
}
}
}
}
m
上个效果图:卧槽,我的浏览器抽风了,点插入图片没反应,自己运行吧
R语言数组和矩阵1 数组
数组可以看成一个由递增下标表示的数据项的集合,例如数值。
数组的生成
如果一个向量需要在R中以数组的方式被处理,则必须含有一个维数向量作为它的dim属性。
维度向量由dim()指定,例如,z是一个由1500个元素组成的向量。下面的赋值语句
>dim(z) <- c(3,5,100)使它具有dim属性,并且将被当作一个3X5X100的数组进行处理。 c(3,5,100) 就是他的维度向量。
还可以用到像matrix()和array()这样的函数来赋值。比如
>array(1:20, dim=c(4,5))
>matrix(1:24, 3,4)
数据向量中的值被赋给数组中的值时,将遵循与FORTRAN相同的原则"主列顺序",即第一个下标变化的最快,最后的下标变化最慢。
数组的运算
数组可以在算数表达式中使用,结果也是一个数组,这个数组由数据向量逐个元素的运算后组成,通常参与运算的对象应当具有相同的dim属性。
2 数组的索引和数组的子块
数组中的单个元素可以通过下标来指定,下标由逗号分隔,写在括号内。
我们可以通过在下标的位置给出一个索引向量来指定一个数组的子块,不过如果在任何一个索引位置上给出空的索引向量,则相当于选取了这个下标的全部范围。
如a[2,,],a[,3,]等
3 索引数组
除了索引向量,还可以使用索引数组来指定数组的某些元素。
例如:有4X5的数组a,若要得到a中的a[1,3], a[2,2] 和a[3,1]这三个元素,可以生成索引向量i,然后用a[i]得到它们。
>a <- array(1:20,dim=c(4,5)) # Generate a 4 by 5 array.
>i <- array(c(1:3,3:1),dim=c(3,2))
>i
[,1] [,2]
[1,] 1 3
[2,] 2 2
[3,] 3 1
>a[i]
[1] 9 6 3
>a[i] <- 0 # 将这三个元素用0替换。
4 向量,数组的混合运算
表达式从左到右被扫描;
参与运算的任意对象如果大小不足,都将被重复使用直到与其他参与运算的对象等长;
当较短的向量和数组在运算中相遇时,所有的数组必须具有相同的dim属性,否则返回一个错误;
如果有任意参与运算的向量比参与运算的矩阵或数组长,将会产生错误;
如果数组结构正常声称,并且没有错误或者强制转换被应用于向量上,那么得到的结果与参与运算的数组具有相同的dim属性。
5 矩阵的运算
构建分区矩阵:cbind()和rbind(),cbind()按照水平方向,或者说按列的方式将矩阵连接到一起。rbind()按照垂直的方向,或者说按行的方式将矩阵连接到一起。
外积: *** 作符是%o%:
>ab <- a %o% b 或者
>ab <- outer(a, b, "*")
其中的乘法 *** 作可以由任意一个双变量的函数替代。
广义转置:函数t(A),或aperm(A, c(2,1));
获取行数/列数:nrow(A)和ncol(A)分别返回矩阵A的行数和列数。
矩阵乘法: *** 作符为%*%;
交叉乘积(cross product):crossprod(X,Y)等同于t(X) %*% y,crossprod(X)等价于crossprod(X, X);
diag(v):如果v是向量,diag(v)返回一个由v的元素为对角元素的对角矩阵。
如果v为矩阵,diag(v)返回一个由v主对角元素组成的向量。
如果v只是一个数值,那么diag(v)是一个vXv的单位矩阵。
特征值和特征向量:eigen(Sm)。这个函数的结果是由名为values和vectors的两部分组成的列表。如果只是需要特征值:eigen(Sm)$values
最小二乘拟合即QR分解:lsfit(), qr()。
强制转换为向量:as.vector(),或者直接c().
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)