▶️ 查看代码
[,1] [,2] [,3] [,4]
[1,] 120 135 128 150
[2,] 80 95 88 100
[3,] 200 210 205 220
第4讲:矩阵、列表、数组与数据框——更多数据对象
2026年09月09日
Matrix · List · Array · Data Frame
提示
今天把R语言的数据对象工具箱补充完整,前半节认识矩阵、列表、数组,后半节回到最常用的数据框,学几招更好用的处理方式——学完今天,你会拥有六件趁手的工具:向量、矩阵、数组、因子、列表、数据框。
为什么还需要更多数据对象?
复习口诀:“文本最强,遇串皆串”——这个隐式转换的逻辑,今天在矩阵里还会用到。
问题一:如果要表示“3家公司 × 4个季度”的营收数据(一张12格的表),向量装得下吗?
能装,但没有“行列”结构,不好按行按列取数——这就是矩阵要解决的问题
问题二:如果想把“公司名称、成立年份、是否上市、近三年营收”这些类型各不相同的信息打包在一起,数据框只能存“等长的列”,能满足吗?
不能——这就是列表要解决的问题
数据框是最常用的“表格”,但矩阵(纯数值的表格)、列表(万能百宝箱)、数组(多维表格)是数据框做不到的场景下的补充工具——今天把工具箱补充完整之后,后半节课再回到数据框,学几招更好用的处理方式
二维的同类型数据
警告
nrow=3告诉R这是3行;byrow=TRUE表示按行填充数据——注意:R默认按列填充(byrow=FALSE),这是新手最容易踩的坑,现场对比两种填充方式的差异。
注记
矩阵和向量一样,所有元素必须是同一种数据类型(复习“文本最强,遇串皆串”——矩阵中混入一个字符串,整个矩阵都会变成字符串型)。
Q1 Q2 Q3 Q4
贵州茅台 120 135 128 150
五粮液 80 95 88 100
泸州老窖 200 210 205 220
Q1 Q2 Q3 Q4
120 135 128 150
[1] 88
课堂练习:取出泸州老窖全年的营收数据(提示:用行名索引)
提示
和revenue_matrix["五粮液", "Q3"]是同一套逻辑——只指定行名、不指定列名,即取出该行的全部列。
财务报表怎么用矩阵表示
用rowSums()计算三家公司的年度总营收,再结合which.max()与rownames()找出年度营收最高的公司
提示
which.max()返回的是位置(第几个),不是公司名,所以要配合rownames()把位置翻译回名字——这个组合以后会经常用到。
什么都能装的百宝箱
类比:向量、矩阵要求元素类型一致,数据框要求每列等长;列表没有这些限制——可以同时装数值、字符串、向量、数据框,甚至列表本身
[1] "贵州茅台"
[1] 120 135 128 150
[1] 120 135 128 150
$quarterly_revenue
[1] 120 135 128 150
重要
[ ]取出的是“仍然装在列表里的一份”(打开看还是个盒子),[[ ]]取出的是“盒子里真正的内容”——这是列表最容易搞混的地方,现场对比class(company_info[4])和class(company_info[[4]])的输出差异。这个知识点待会儿在数据框进阶环节还会用到,请务必掌握。
创建一个列表,包含某公司的名称、成立年份、近三年营收(向量)、信用评级(因子),并用$取出营收向量计算平均值
提示
四个元素、四种类型(字符、数值、数值向量、因子)装在同一个列表里——这正是列表“什么都能装”的体现,换成数据框是做不到的。
矩阵的多维升级版
类比:矩阵是二维(行×列)的表格,数组可以是三维甚至更多维(如“公司×季度×年份”的三维营收数据)
注记
数组在实际财务分析中不算高频工具(多数场景用数据框或列表就足够了),此处只需要“眼熟”,知道R语言有这个工具、遇到多维数据时可以考虑它即可,不安排课堂练习。
向量、矩阵、数组这一条“同类型、维度递增”的家族已经认识完整,回到最常用的数据框,学几招更好用的处理方式
'data.frame': 3 obs. of 4 variables:
$ company : chr "贵州茅台" "五粮液" "泸州老窖"
$ revenue_2025: num 1500 680 320
$ profit_2025 : num 750 200 90
$ listed : logi TRUE TRUE TRUE
company revenue_2025 profit_2025 listed
Length :3 Min. : 320 Min. : 90 Mode:logical
N.unique :3 1st Qu.: 500 1st Qu.:145 TRUE:3
N.blank :0 Median : 680 Median :200
Min.nchar:3 Mean : 833 Mean :347
Max.nchar:4 3rd Qu.:1090 3rd Qu.:475
Max. :1500 Max. :750
[1] 3 4
[1] 3
[1] 4
[1] "company" "revenue_2025" "profit_2025" "listed"
这个写法是不是很眼熟?第2课学过revenue[revenue > 130]对向量做筛选,这里是对数据框的行做同样的事。
注记
预告:下节课/项目二会学dplyr::filter(df, revenue_2025 > 500),效果完全一样,只是写法更顺手——今天先打好base R的底子。
重要
呼应四、列表小节:数据框每一列可以是不同类型(revenue_2025数值型、listed逻辑型),但所有列必须等长——这正是“特殊的列表”。
从df中筛选出“上市且营收超过500”的公司(提示:用&连接两个逻辑条件,写法与向量的多条件筛选一致),并计算这些公司的平均利润率(profit_2025/revenue_2025)
提示
df$listed & df$revenue_2025 > 500先各自生成一个逻辑向量,再用&按位置“与”起来——和第2课向量的多条件筛选(如revenue > 100 & revenue < 200)是完全一样的写法。
把六大数据对象串成一张体系图
flowchart TD
V["向量 Vector<br/>一维,同类型"]
V --> M["矩阵 Matrix<br/>二维,同类型"]
M --> AR["数组 Array<br/>多维,同类型"]
V --> F["因子 Factor<br/>带类别标签的向量"]
V --> L["列表 List<br/>一维,任意类型"]
L --> DF["数据框 Data Frame<br/>列等长的特殊列表"]
style V fill:#1a3a5c,color:#fff
style M fill:#2e5984,color:#fff
style AR fill:#2e5984,color:#fff
style F fill:#375623,color:#fff
style L fill:#7a4419,color:#fff
style DF fill:#7a4419,color:#fff
提问串联:数据框的本质是什么?——六(3)刚验证过:是一种特殊的列表,每一列可以是不同类型,但所有列必须等长,取值方式$和[[ ]]与列表完全一致。
对照一下,今天这几件事你都做到了吗?
rowSums()/colSums()等函数对矩阵进行汇总[ ]与[[ ]]的取值差异str()、条件筛选对数据框做进阶操作,并说出“数据框是特殊列表”的原理提示
如果有没打勾的,下课后一定要找同学或老师补上,不要留到下一讲。
请花1分钟,在纸条或在线问卷上简要回答:
[ ]和[[ ]]取数有什么不同?[ ]取出的结果仍然是一个列表(打开还是个盒子),[[ ]]取出的是盒子里真正的内容(脱离了列表这层包装)——可以用class()验证两者输出类型不同。is.list(df)返回TRUE——数据框本质上就是一种列表,取值方式($、[[ ]])与列表完全一致,只是数据框额外要求“每一列必须等长”,这是数据框相比普通列表多出来的限制。提示
对照一下自己纸条上写的答案,理解偏差的地方现在举手提问,别留到下节课。
使用Quarto(.qmd)完成以下操作,保留代码与运行结果:
rowSums()或直接计算,求出每个季度的利润率(利润/营收)$和[[ ]]两种方式取出其中一个元素[ ]和[[ ]]取同一个元素时class()的差异,并用一句话写出你的理解df的基础上(或自建一个至少4列的数据框),完成:
提交要求
提交今天课堂上练习的.qmd源文件,命名为“学号_姓名_第4课作业”,确保代码可运行、结果完整。本次作业计入平时成绩中的“实验报告”部分考核。
第5讲:流程控制语句——条件分支、循环、自定义函数
if/else)、循环(for/while)、自定义函数(function)提示
课前准备:整理好今天创建的revenue_matrix、company_info、df等对象的代码,下节课会用到类似的数据结构。
第4讲:矩阵、列表、数组与数据框——更多数据对象
"In God we trust; all others must bring data." — W. Edwards Deming,质量管理与统计学家
朱 奇 | 锦城大学 · 财会学院
数据挖掘与R语言 | 第4讲:矩阵、列表、数组与数据框——更多数据对象