R导论学习笔记(五):数组和矩阵

1
`数组和矩阵的联系:一个矩阵只是一个二维的数组`
1
`向量只有在定义了 dim 属性后才能作为数组在R 中使用。假定,z是一个含1500个元素的向量。那么> dim(z) <- c(3,5,100)对dim 属性的赋值使得该向量成一个3 ×5 ×100 的数组。`
1
`数据向量(data vector)的值在数组中的排列顺序采用 FORTRAN 方式的数组元素次序,即“按列次序”,也就是说第一下标变化最快,最后下标变化最慢。假定数组a的维数向量是c(3,4,2),则a 中有3×4×2 = 24 元素,依次为a[1,1,1],a[2,1,1], ..., a[2,4,2], a[3,4,2]。`
1
2
3
延续前面的例子,a[2,,] 是一个4 × 2 的数组。它的维度向量为c(4,2),数据向量依次包括下面的值

c(a[2,1,1], a[2,2,1], a[2,3,1], a[2,4,1],a[2,1,2], a[2,2,2], a[2,3,2], a[2,4,2])
1
a[,,]表示整个数组。这和忽略下标直接使用a 效果是一样的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
假定我们有一个4 ×5 的数组X,我们可以做如下的事情:
• 以向量的格式取出元素X[1,3], X[2,2] 和X[3,1],
• 在数组X 中用0替换这些元素。在这个例子中,我们需要一个3 ×2 的下标数组,见下面的代码。

# 注意顺序是按列加上去的
> x <- array(1:20, dim=c(4,5)) # 产生一个 4 × 5 的数组。
> x
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 20

> i <- array(c(1:3,3:1), dim=c(3,2))
> i # i 是一个 3 × 2 的索引矩阵。
[,1] [,2]
[1,] 1 3
[2,] 2 2
[3,] 3 1
> x[i] # 提取这些元素。
[1] 9 6 3
> x[i] <- 0 # 用0替换这些元素。
> x
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 0 13 17
[2,] 2 0 10 14 18
[3,] 0 7 11 15 19
[4,] 4 8 12 16 20
>
1
`cbind和rbind分别是根据列和行合并,例如ib <- cbind(1:5, 2)> ib     [,1] [,2][1,]    1    2[2,]    2    2[3,]    3    2[4,]    4    2[5,]    5    2`
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
在R中求单变量的频次,直接使用table函数就可以了,比如:

> table(rpois(100,5))
0 1 2 3 4 5 6 7 8 9 10
1 4 9 22 22 11 11 13 3 2 2

同样的,可以使用table函数来求两个或多个变量之间的列联表,比如:
> table(rpois(100,2),rpois(100,1))
0 1 2 3 4 5
0 7 4 3 0 0 0
1 8 7 6 1 1 0
2 14 14 2 2 0 1
3 6 7 1 1 0 0
4 2 3 4 2 0 0
5 1 0 0 0 1 0
6 0 2 0 0 0 0
1
`除了用设定一个向量dim 属性的方法来构建数组,它还可直接通过函数array 将向量转换得到,具体格式为> Z <- array(data vector , dim vector )> Z <- array(0, c(3,4,2))这样就会使得Z 是一个所有值都是0的3 ×4 ×2 数组`
1
`数组可用于算术表达式中,并且结果就是一个基于数据向量的对应元素运算而得到的数组。所有操作数的属性dim 必须一致`
1
2
3
4
5
6
7
8
9
10
11
12
所谓数组(或向量)a和b的外积,指的是a的每一个元素和b的每一个元素搭配在一起相乘得到的新元素.当然运算规则也可自定义.外积运算符为 %o%(注意:百分号中间的字母是小写的字母o),也可以用> ab <- outer(a, b, "*")
例如:

> a <- 1:2
> b <- 3:5
> d <- a %o% b
> d
[,1] [,2] [,3] # a的每一个元素和b的每一个元素搭配在一起相乘
[1,] 3 4 5
[2,] 6 8 10
注意维数公式为:
dim(d) = c( dim(a) , dim(b) )
1
广义转置:我们可以用命令B <- t(A)表示矩阵A转置,函数nrow(A) 和ncol(A) 将会分别返回矩阵A 的行数和列数。
1
2
3
4
5
6
7
8
9
10
11
12
A*B表示矩阵元素对应相乘(要求行列相同),A%*%B表示矩阵乘法,行列式用法(要求满足m,k × k,n)。

a <- array(1:9,c(3,3))
b <- array(2,c(3,3))a*ba%*%b
[,1] [,2] [,3]
[1,] 2 8 14
[2,] 4 10 16
[3,] 6 12 18
[,1] [,2] [,3]
[1,] 24 24 24
[2,] 30 30 30
[3,] 36 36 36
1
`函数crossprod() 可以完成“矢积”(crossproduct)运算,也就是说crossprod(X,y) 和t(X) %*% y 等价,但是在运算上更为高效.如果crossprod() 第二个参数忽略了,它将默认和第一个参数一样,即第一个参数和自己进行运算`
1
`函数diag() 的含义依赖于它的参数。当v 是一个向量时,diag(v)返回以该向量元素为对角元素的对角矩阵。当M 是一个矩阵时,diag(M) 返回M的对角元素。这和Matlab 中diag() 的用法完全一致。不过有点混乱的是,如果k 是单个值,那么diag(k) 的结果就是k ×k 的方阵!`
1
`求解线性方程组是矩阵乘法的逆运算。当下面的命令运行后,> b <- A %*% x(想象多元方程组形式,A的行数为样本数)。如果仅仅给出A 和b,那么x 就是该线性方程组的根。在R 里面,用命令> solve(A,b)求解线性方程组,并且返回x (可能会有一些精度丢失)。注意,在线性代数里面该值表示为x = A−1b ,其中A−1表示A的逆(inverse)。矩阵的逆可以用下面的命令计算,solve(A)不过一般很少用到。在数学上,用直接求逆的办法解x <- solve(A) %*% b相比solve(A,b)不仅低效而且还有一种潜在的不稳定性。用于多元计算的二次型xA−1x可以通过像x %*% solve(A,x)的方式计算得到,而不是直接计算A 的逆。`
1
2
3
函数eigen(Sm) 用来计算矩阵Sm 的特征值和特征向量。这个函数的返回值是一个含有values 和vectors 两个分量的列表。ev$val 表示Sm 的特征值向量ev$vec 则是相应特征向量构成的一个矩阵。假定我们仅仅需要特征值,我们可以采用如下的命令:

> evals <- eigen(Sm)$values
1
`函数svd(M) 可以把任意一个矩阵M作为一个参数, 且对M 进行奇异值分解。这包括一个和M 列空间一致的正交列U 的矩阵,一个和M 行空间一致的正交列V 的矩阵,以及一个正元素D 的对角矩阵,如M = U %*% D %*% t(V)`
1
2
3
函数lsfit() 返回最小二乘法拟合(Least squares fitting)的结果列表。赋值可以采用入下命令

> ans <- lsfit(X, y)但实际上,你在回归分析中可能已经习惯使用lm(.) (见线性模型<页码:70>部分) 而不是lsfit()。
1
2
3
4
5
6
单个因子会把各部分数据分成不同的组。类似的是,一对因子可以实现交叉分组等。 函数table() 可以从等长的不同因子中计算出频率表。如果有k 个因子参数,那么结果将是一个k-维的频率分布数组。假定statef 是一个设定数据向量元素个体所在州的因子,那么下面的赋值

> statefr <- table(statef)
将会把一个样本中各种状态的频率分布表赋给statefr。这些频率会被排序且以因子的水平特性标记。等价但有点烦琐实现方式如下

> statefr <- tapply(statef, statef, length)
-------------Thanks for Reading!-------------