学习《统计建模与R软件》(薛毅2006)这本书,使用R语言对书中练习题解答。矩阵分析为书中第二章内容,练习题如下:
2.1 建立一个R文件,在文件中输入变量 \(x = (1, 2, 3)^T\),\(y = (4, 5, 6)^T\),并作以下运算。
(1)计算\(z = 2x + y + e\),其中\(e = (1, 1, 1)^T\);
(2)计算\(x\)和\(y\)的内积;
(3)计算\(x\)和\(y\)的外积。
解:
x <- c(1, 2, 3)
y <- c(4, 5, 6)
e <- c(1, 1, 1)
#建立向量x,y和e
z = 2*x + y + e
print(z) #第一问矩阵加法计算
## [1] 7 10 13
x %*% y #第二问矩阵内积计算,或者使用crossprod(x, y)
## [,1]
## [1,] 32
x %o% y #第三问矩阵外积计算,或者使用tcrossprod(x, y)
## [,1] [,2] [,3]
## [1,] 4 5 6
## [2,] 8 10 12
## [3,] 12 15 18
2.2 将1,2,…,20构成两个\(4 × 5\)阶的矩阵,其中矩阵A是按列输入,矩阵B是按行输入,并作如下运算。
(1)\(C = A + B\);
(2)\(D = AB\);
(3)\(E = (e_{ij})_{n×n}\),其中\(e_{ij} = a_{ij}×b_{ij}\);
(4)\(F\)是由\(A\)的前三行和前三列构成的矩阵;
(5)\(G\)是由矩阵\(B\)的各列构成的矩阵,但不含B的第三列。
解:
A <- matrix(1:20, nrow = 4)
B <- matrix(1:20, nrow = 4, byrow = TRUE)
#建立矩阵A,B
C = A + B
print(C) #第一问矩阵加法
## [,1] [,2] [,3] [,4] [,5]
## [1,] 2 7 12 17 22
## [2,] 8 13 18 23 28
## [3,] 14 19 24 29 34
## [4,] 20 25 30 35 40
#D = A %*% B
#print(D) #第二问两个矩阵的乘积,题目出错了
E = A * B
print(E) #第三问两个矩阵中对应项乘积计算
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 10 27 52 85
## [2,] 12 42 80 126 180
## [3,] 33 84 143 210 285
## [4,] 64 136 216 304 400
F <- A[1:3, 1:3]
print(F) #第四问
## [,1] [,2] [,3]
## [1,] 1 5 9
## [2,] 2 6 10
## [3,] 3 7 11
G <- B[ ,-B[,3]]
print(G) #第五问
## [,1] [,2] [,3] [,4]
## [1,] 1 2 4 5
## [2,] 6 7 9 10
## [3,] 11 12 14 15
## [4,] 16 17 19 20
2.3 构造一个向量\(x\),向量是由5个1,3个2,4个3,2个4构成,注意通道rep()函数。 解:
x <- c(rep(1, 5), rep(2, 3), rep(3, 4), rep(4, 2))
print(x)
## [1] 1 1 1 1 1 2 2 2 3 3 3 3 4 4
2.4 生成一个5阶的Hilbert矩阵, \(H = (h_{ij})_{n×n}\),\(h_{ij} = \frac{1}{i + j + 1}\),\(i,j = 1,2,…,n\)。 (1)计算Hilbert矩阵H的行列式; (2)求H的逆矩阵; (3)求H的特征值和特征向量。 解:
H <- array(0, dim = c(5,5))
for (i in 1:5){for (j in 1:5){H[i, j] = 1/(i+j-1)}}
print(H) #建立矩阵H,第一问
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1.0000000 0.5000000 0.3333333 0.2500000 0.2000000
## [2,] 0.5000000 0.3333333 0.2500000 0.2000000 0.1666667
## [3,] 0.3333333 0.2500000 0.2000000 0.1666667 0.1428571
## [4,] 0.2500000 0.2000000 0.1666667 0.1428571 0.1250000
## [5,] 0.2000000 0.1666667 0.1428571 0.1250000 0.1111111
solve(H) #第二问
## [,1] [,2] [,3] [,4] [,5]
## [1,] 25 -300 1050 -1400 630
## [2,] -300 4800 -18900 26880 -12600
## [3,] 1050 -18900 79380 -117600 56700
## [4,] -1400 26880 -117600 179200 -88200
## [5,] 630 -12600 56700 -88200 44100
eigen(H) #第三问
## $values
## [1] 1.567051e+00 2.085342e-01 1.140749e-02 3.058980e-04 3.287929e-06
##
## $vectors
## [,1] [,2] [,3] [,4] [,5]
## [1,] -0.7678547 0.6018715 -0.2142136 0.04716181 0.006173863
## [2,] -0.4457911 -0.2759134 0.7241021 -0.43266733 -0.116692747
## [3,] -0.3215783 -0.4248766 0.1204533 0.66735044 0.506163658
## [4,] -0.2534389 -0.4439030 -0.3095740 0.23302452 -0.767191193
## [5,] -0.2098226 -0.4290134 -0.5651934 -0.55759995 0.376245545
2.5 已知有5名学生的数据,如下表所示,用数据框的形式读入数据。
表:学生数据
序号 | 姓名 | 性别 | 年龄 | 身高(cm) | 体重(kg) |
---|---|---|---|---|---|
1 | 张三 | 女 | 14 | 156 | 42.0 |
2 | 李四 | 男 | 15 | 165 | 49.0 |
3 | 王五 | 女 | 16 | 157 | 41.5 |
4 | 赵六 | 男 | 14 | 162 | 52.0 |
5 | 丁一 | 女 | 15 | 159 | 45.5 |
解:
num <- c(1:5)
name <- c("张三", "李四", "王五", "赵六", "丁一")
gender <- c("女", "男", "女", "男", "女")
age <- c(14, 15, 16, 14, 15)
high <- c(156, 165, 157, 162, 159)
weigh <- c(42.0, 49.0, 41.5, 52.0, 45.5)
#建立向量
students <- data.frame(num, name, gender, age, high, weigh)
colnames(students) <- c("序号", "姓名", "性别", "年龄", "身高(cm)", "体重(kg)")
print(students)
## 序号 姓名 性别 年龄 身高(cm) 体重(kg)
## 1 1 张三 女 14 156 42.0
## 2 2 李四 男 15 165 49.0
## 3 3 王五 女 16 157 41.5
## 4 4 赵六 男 14 162 52.0
## 5 5 丁一 女 15 159 45.5
#建立数据框
2.6 将2.5中的数据表的数据写成一个纯文本文件,用函数read.table()读该文件,然后再用函数write.csv()写成一个能用Excel表打开的文件,并用Excel表打开。 解:
write.table(students, file = "students.txt") #写成txt纯文本文件
a <- read.table("students.txt", sep = "", header = T)
print(a) #读取txt纯文本文件
## 序号 姓名 性别 年龄 身高.cm. 体重.kg.
## 1 1 张三 女 14 156 42.0
## 2 2 李四 男 15 165 49.0
## 3 3 王五 女 16 157 41.5
## 4 4 赵六 男 14 162 52.0
## 5 5 丁一 女 15 159 45.5
write.csv(students, file = "studens.csv") #写成csv文件
2.7 编写一个R程序(函数)。输入一个整数n,如果n≤0,则终止运算,并输出一句话:『要求输出一个正整数』;否则,如果n是偶数,则将n除2,并赋值给n;否则将3n+1赋给n。不断循环,直到n = 1,才停止计算,并输出一句话:『运算成功』。这个例子是为了检验数论中的一个简单的定理。
解:
F <- function(n){
if(n <= 0)
print("要求输出一个正整数")
else{
repeat{
if(n == 1)break
else if(n %% 2 == 0){n <- n/2}
else n <- 3*n + 1
}
print("运算成功")
}
}
F(90)
## [1] "运算成功"
F(0)
## [1] "要求输出一个正整数"