- 实验目的:
- 掌握矩阵的相关函数和下标运算;
- 掌握数组的相关函数和下标运算;
- 掌握列表的定义和相关函数;
- 掌握数据框的定义和相关函数。
实验内容:
矩阵的生成。在R语言中,有两种生成矩阵的方法:
利用dim()函数给向量定义维数向量(dim属性),将向量转换成矩阵
用matrix()函数直接生成矩阵
利用上述函数完成以下小题,并将代码和运行结果截图粘贴于每小题之下的空行。
利用dim()函数将向量1:12(向量名为A)转换成一个3行4列的矩阵A。
利用matrix()函数直接生成与上一小题一模一样的矩阵B(利用matrix()函数中的两个参数nrow或ncol,这两个参数也可分别简写为nr、nc)。
将上一小题matrix()函数中的添加一个参数byrow,并将此参数赋值为T,比较生成的矩阵C与上一小题的矩阵B有何不同。
数据变成按行放置。
矩阵的下标运算。矩阵的下标运算与向量类似,需要使用方括号“[]”,但与向量不同的是,方括号中需要写两个部分,第一部分表示行,第二部分表示列,两部分中间用“,”隔开。矩阵的下标运算有以下几种情况:
正数或由多个正数构成的向量(此时是取下标对应的元素)
负数或由多个负数构成的向量(此时是去掉下标对应的元素)
利用第1题的矩阵B,完成以下练习,并将代码和运行结果截图粘贴于每小题之下的空行。
取出矩阵B的第2行第3列对应的元素。
生成一个新矩阵,它是由矩阵B的第1,3行,第2,4列对应的元素组成。
生成一个新矩阵,它是由矩阵B的第2,4列对应的元素组成。
生成一个新矩阵,它是由矩阵B去掉第3行对应的元素后剩下的元素组成。
生成一个新矩阵,它是由矩阵B去掉第2行,去掉第1,4列对应的元素后剩下的元素组成。
生成一个新矩阵,它是由矩阵B去掉第2行后,保留矩阵B的第1,4列对应的元素组成。
生成一个新矩阵,它是将矩阵B的第1列三个元素重新赋值为11:13,其它元素保持不变构成
矩阵的下标运算(续)。矩阵的下标除了可以是数和向量外(上题),还可以是一个矩阵。将矩阵的第i行j列记为[i, j]。现要求同时选出上题中矩阵B的 [1, 1], [1, 3], [2, 4], [3, 4] 共4个元素生成一个向量。试用下面两种方法完成。
法一:c(B[1,1], B[1,3], B[2,4], B[3,4])
法二:先定义一个矩阵D,用来存放这4个元素的下标,矩阵D的第一列用来存放每个元素的行号,第二列用来存放每个元素的列号。显然矩阵D是一个4行2列的矩阵,然后将矩阵D做为矩阵B的下标(即B[D]),即可得出与法一同样的结果。
矩阵的合并运算。矩阵的合并运算包括两个方向上的合并运算:
行合并:函数rbind()把两个相同列数的矩阵纵向(行数增加)拼成一个大矩阵
列合并:函数cbind()把两个相同行数的矩阵横向(列数增加)拼成一个大矩阵
完成以下练习,并将代码和运行结果截图粘贴于每小题之下的空行。
生成三矩阵ma=,mb=
,mc=
选出其中两个矩阵进行“行合并”运算。
选出其中两个矩阵进行“列合并”运算。
数组的生成和下标运算。由于矩阵就是二维数组,因此这里主要针对多维数组。与生成矩阵的方法类似,生成数组也有两种方法:
利用dim()函数给向量定义维数向量(dim属性),将向量转换成数组
用array()函数直接生成矩阵(注意理解与matrix()函数的参数不同)
完成以下练习,并在R中运行进行验证。
用arrray()函数将1:24生成一个3*4*2(行*列*层)的数组aa。
分析一下aa[1,,]的结果,并在R中验证。
列表(list)是一种特别的对象集合,它的元素也由序号(下标)区分,但是各元素的类型可以是任意对象,不同元素不必是同一类型,甚至元素还可以是另一个列表。按以下方法创建一个列表L,
L <- list(12, c(34,56), matrix(1:12,nrow=4), 1:15, list(10,11))
注意这里没有为其指定每个元素的名字,运行后注意每个元素的默认名称,并回答以下问题。
L[[2]][2]的输出结果是什么?请先自己写出结果,再运行验证。
56
用1:10替换L的第四个元素,请写出命令,并运行验证。
将L的第五个元素中的11替换为20,请写出命令,并运行验证。
列表元素的引用方法。方法有三种:
列表名[[下标]]
列表名[["元素名"]] (前提是列表指定了元素名字)
列表名$元素名 (前提是列表指定了元素名字)
已知Lst <- list(name="Fred", wife="Mary", no.children=3, child.ages=c(4,7,9)),完成以下练习,并在R中运行进行验证。
Lst[[2]]
Lst[["wife"]]
Lst$wife
数据框(dataframe)通常是矩阵形式的数据,但与矩阵要求所有元素类型必须都为数值不同,数据框各列可以是不同类型的。数据框每列是一个元素(变量),每行是一个观测。
序号 | 姓名 | 性别 | 年龄 | 身高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 |
已知有5名学生的数据,如下表所示。将此数据录入到名为df数据框中。
学生数据
数据框的下标运算与数据的引用。下标运算与矩阵类似,数据引用方法与列表类似。
完成以下练习,并在R中运行进行验证,并好好体会。
在上题的df数据框中,选出李四、丁一两个同学的身高和体重数据。
用类似列表元素的三种引用方法,选出数据框中所有人的身高这一列数据。
分析df[1:2]的结果,并进行验证。
选出第一、二列元素
分析df[, 1:2]的结果,并进行验证。
选出第一、第二列元素
分析df[1:2, ]的结果,并进行验证。
选出第一、二行元素
分析df[-(1:2), ]的结果,并进行验证。
删除第一、第二行元素
引用列表或数据框中的元素,都有三种方法,但这三种方法都需要在元素名前写上列表名或数据框名。但是当列表或数据框名字较长或者要重复很多次引用元素时这样写就很繁琐了,有两种方法可以简化:
使用 with() 函数
使用attach() 函数和detach()函数。但使用attach()导致的错误可能有很多,如数据框中某些元素名与其它对象同名时会覆盖这个同名对象的值,所以慎重使用它!
例如,对于前面第8题中的学生数据,如果想在表中最右边增加一列,给出每个学生的BMI指数,其计算公式为
BMI = 体重(kg) / (身高(m)的平方)
普通方法:df$BMI <- df$体重/(df$身高/100)^2。
简化方法:df$BMI <- with(df, 体重/(身高/100)^2)
用以上任意一种方法为第8题中的学生数据增加BMI这一列,并把最终完成的新数据框展示出来。
思考:(以下运算类型的题目请先进行笔算后,再在R中运算核对)
下面这一脚本的输出结果是什么?
Mat<-matrix(1:12, nrow=4, byrow=TRUE); Mat[3,];Mat[2,2:3]
7 8 9
5 6
执行以下命令后,x1与x2的输出结果是什么?
x1 <- rbind(c(1,2), c(3,4))
x2 <- cbind(c(1,2), c(3,4))
1 2
3 4
1 2
3 4
列表元素除了可以用“列表名[[下标]]”、“列表名[["元素名"]]”这两种方式来引用外,还有哪一种方式?
列表名$元素名
数据框的一个元素是数据框中的一列还是一行,还是其中的某个值?
是一列
列表与数据框有什么异同点?
相同点:
1. 都可以存储多个不同类型的数据对象,如向量、矩阵、其他列表或数据框等。
2. 都可以使用索引(整数、逻辑或名称)来访问和修改元素。
3. 都可以通过`length()`函数获取元素数量。
4. 都可以使用`names()`函数为元素命名。
不同点:
1. 结构不同:列表是一个有序的元素向量,每个元素可以有自己的名称,可以包含不同长度的子元素;数据框是一个类似于矩阵的二维表格,每列可以是不同类型,但每列的长度必须相同。
2. 数据类型不同:列表中的元素可以是任意类型,包括向量、矩阵、函数等;数据框中的每列必须是同一数据类型,可以是数值、字符、因子等。
3. 数据结构不同:列表中的元素可以具有不同的维度,可以是高维数组、矩阵、数据框等;数据框中的每列都是一维向量。
4. 数据处理不同:列表适合储存和处理不同类型或不同长度的数据,可以方便地进行多层嵌套;数据框适合存储和处理二维表格数据,可以进行类似于数据库的操作,如合并、筛选、汇总等。