



综合排名包括各科成绩排名以及语文、数学、英语总分排名和总分排名,实现过程如下(源码位置:资源包\Code\01\rank_data.R)。
(1)在项目文件夹下新建一个R脚本文件,命名为rank_data.R。
(2)使用openxlsx包的read.xlsx()函数读取Excel文件,代码如下:
# 加载程序包
library(openxlsx)
# 读取Excel 文件
df <- read.xlsx("学生成绩统计分析/成绩表 1.xlsx",sheet=1)
(3)分别计算语文、数学、英语总分和排名,主要使用rank()函数,然后使用View()函数以表格形式显示数据,代码如下:
# 各科成绩排名 df$语文排名 <- round(rank(-df$语文,ties.method='min'),0) df$数学排名 <- round(rank(-df$数学,ties.method='min'),0) df$英语排名 <- round(rank(-df$英语,ties.method='min'),0) df$物理排名 <- round(rank(-df$物理,ties.method='min'),0) df$化学排名 <- round(rank(-df$化学,ties.method='min'),0) df$生物排名 <- round(rank(-df$生物,ties.method='min'),0) # 计算语数英总分和排名 df$语数英总分 <- df$语文+df$数学+df$英语 df$语数英排名 <- round(rank(-df$语数英总分,ties.method='min'),0) # 计算总分和排名 df$总分 <- df$语文+df$数学+df$英语+df$物理+df$化学+df$生物 df$总分排名 <- round(rank(-df$总分,ties.method='min'),0) # 以表格形式显示数据 View(df)
运行程序,结果如图1.26所示。
图1.26 综合排名(部分数据截图)
从运行结果得知:通过语文、数学、英语总分的排名和总分排名可以看出有些学生存在偏科现象。(4)将计算结果和排名写入Excel文件中,代码如下:
write.xlsx(df,"学生成绩统计分析/排名.xlsx")
运行程序,计算结果和排名将写入Excel文件中,打开Excel文件,结果如图1.27所示。
图1.27 排名.xlsx
通过绘制各科成绩直方图查看各科成绩的分布情况,主要使用hist()函数,实现过程如下(源码位置:资源包\Code\01\hist_data.R)。
(1)在项目文件夹下新建一个R脚本文件,命名为hist_data.R。
(2)使用openxlsx包的read.xlsx()函数读取Excel文件,代码如下:
# 加载程序包
library(openxlsx)
# 读取Excel 文件
df <- read.xlsx("学生成绩统计分析/成绩表 1.xlsx",sheet=1)
(3)使用par()函数创建2行3列的绘图区域,然后使用hist()函数绘制各科成绩直方图,代码如下:
# 2 行 3 列的绘图区域 par(mfrow = c(2,3)) # 绘制各科成绩直方图 hist(df$语文,main="",xlab="语文") hist(df$数学,main="",xlab="数学") hist(df$英语,main="",xlab="英语") hist(df$物理,main="",xlab="物理") hist(df$化学,main="",xlab="化学") hist(df$生物,main="",xlab="生物")
运行程序,结果如图1.28所示。
图1.28 直方图分析各科成绩
(4)通过偏度系数判断偏度,主要使用timeDate模块的skewness()函数进行计算,代码如下:
# 计算偏度系数(正值为右偏,负值为左偏) df1 <- df[,3:8] n1 <- timeDate::skewness(df1) n1
运行程序,结果如下:
语文 数学 英语 物理 化学 生物 -0.1335115 0.6028185 -0.4783041 -1.1768642 -1.6404522 -1.4271909
从运行结果得知:“数学”成绩呈右偏态分布,即直方图右侧缺失,说明高分段学生缺失,试卷有难度。其他学科呈左偏态分布,即直方图左侧缺失,说明低分段学生较少,试卷难度适中。
说明
负偏态分布,也称为左偏态,指的是在一个不对称或偏斜的次数分布中,次数分布的高峰偏右,而长尾则从右逐渐延伸于左端。这种分布的特点是偏态系数小于零,意味着众数位于较大分数或量数的一侧(右侧),而长尾则位于较小分数或量数的一侧(左侧)。在学生的学业成绩分布中,负偏态分布表明高分人数很多,低分人数很少,这通常意味着测试的难度较低,考试要求低于教学要求,或者学生的基础较好。因此,当学生成绩呈现负偏态分布时,说明测验的整体难度相对偏易。
此外,负偏态分布的原因可能包括试题难度过小,导致部分学生成绩过高,从而使总分的分布呈现负偏态。这种情况下,测验的整体难度被认为是正常的。然而,需要注意的是,负偏态分布并不总是意味着测验难度过低,它也可能反映试题难度介于过大和过小之间,导致一部分学生不能正常发挥。因此,在解释负偏态分布时,需要综合考虑试题的难度设置和学生的实际表现。
通过绘制箱形图分析各科成绩,主要使用boxplot()函数,实现过程如下(源码位置:资源包\Code\01\box_data.R)。
(1)在项目文件夹下新建一个R脚本文件,命名为box_data.R。
(2)使用openxlsx包的read.xlsx()函数读取Excel文件,代码如下:
# 加载程序包
library(openxlsx)
# 读取Excel 文件
df <- read.xlsx("学生成绩统计分析/成绩表 1.xlsx",sheet=1)
(3)使用par()函数创建2行3列的绘图区域,然后使用boxplot()函数绘制各科成绩箱形图,代码如下:
# 2 行 3 列的绘图区域 par(mfrow = c(2,3)) # 绘制各科成绩箱形图 boxplot(df$语文,main="",xlab="语文") boxplot(df$数学,main="",xlab="数学") boxplot(df$英语,main="",xlab="英语") boxplot(df$物理,main="",xlab="物理") boxplot(df$化学,main="",xlab="化学") boxplot(df$生物,main="",xlab="生物")
运行程序,结果如图1.29所示。
从运行结果得知:语文、英语和物理成绩比较平均。另外,语文、数学、物理、化学和生物均存在异常值。
图1.29 箱形图分析各科成绩
对各科最高分和最低分状况进行分析时,首先使用max()函数和min()函数分别计算各科成绩的最高分和最低分。需要注意的是,在求得物理、化学和生物3科的最小值后,应排除分数为0的数据,因为在1.6.2节中我们将物理、化学和生物3科的缺失值填充为0了。然后绘制各科成绩最高分和最低分柱形图。实现过程如下(源码位置:资源包\Code\01\max_min_data.R)。
(1)在项目文件夹下新建一个R脚本文件,命名为max_min_data.R。
(2)使用openxlsx包的read.xlsx()函数读取Excel文件,代码如下:
# 加载程序包
library(openxlsx)
# 读取Excel 文件
df <- read.xlsx("学生成绩统计分析/成绩表 1.xlsx",sheet=1)
(3)使用max()函数和min()函数分别计算各科成绩最高分和最低分,并排除物理、化学和生物3科分数为0的数据,代码如下:
# 计算各科成绩最高分和最低分 y1_max <- max(df$语文) y1_min <- min(df$语文) y2_max <- max(df$数学) y2_min <- min(df$数学) y3_max <- max(df$英语) y3_min <- min(df$英语) y3_max <- max(df$英语) y3_min <- min(df$英语) y4_max <- max(df$物理) # 最低分排除分数为 0 的数据 y4_min <- min(df[df$物理!=0,'物理']) y5_max <- max(df$化学) y5_min <- min(df[df$化学!=0,'化学']) y6_max <- max(df$生物) y6_min <- min(df[df$生物!=0,'生物'])
(4)通过求得的各科成绩的最高分和最低分创建6*2的矩阵,代码如下:
# 创建 6*2 的矩阵
datas <- matrix(c(y1_max,y2_max,y3_max,y4_max,y5_max,y6_max,
y1_min,y2_min,y3_min,y4_min,y5_min,y6_min),6,2,
dimnames =list(names(df[,3:8])))
# 矩阵行列转置
datas <-t(datas)
datas
运行程序,结果如下:
语文 数学 英语 物理 化学 生物 [1,] 113.5 148 110.5 99 90 83 [2,] 80.0 43 48.5 30 24 12
(5)使用barplot()函数绘制各科成绩最高分和最低分柱形图,代码如下:
# 绘制柱形图
# 自定义画布大小
par(pin=c(5,4))
# 绘制柱形图
p=barplot(height = datas,
col = c('darkorange','deepskyblue'), # 每个柱形的颜色
beside=TRUE, # 分组柱形图,即多柱形图
border=FALSE, # 无边框
ylim=c(0,160)) # y 轴坐标轴范围
# 添加文本标签
text(p,datas+5,labels=datas)
运行程序,结果如图1.30所示。
图1.30 柱形图分析各科最高分和最低分状况
从运行结果得知:除了语文,其他各科成绩最高分和最低分差距还是比较大的。
各科中上等成绩统计分析,主要统计各科成绩超过平均分的人数。通常来讲,如果学生的成绩在班级里达到或超过了平均分,那么其基本就属于中上等学生,即使是在平均分上下,不是幅度相差太大都可以算得上是中上等学生。例如,一个班级有50个人,那么成绩达到平均分也就是25名左右,只要成绩排在25~30名都算是中等成绩。成绩高于平均分,只能说明成绩处于中等偏上的水平,属于比较不错的学习成绩。
下面实现各科中上等成绩统计分析。首先使用apply()函数计算平均分,然后使用length()函数和mean()函数统计各科成绩大于平均分的人数,最后使用barplot()函数绘制柱形图,实现过程如下(源码位置:资源包\Code\01\mean_data.R)。
(1)在项目文件夹下新建一个R脚本文件,命名为mean_data.R。
(2)使用openxlsx包的read.xlsx()函数读取Excel文件,然后抽取数据,代码如下:
# 加载程序包
library(openxlsx)
# 读取Excel 文件
df <- read.xlsx("学生成绩统计分析/成绩表 1.xlsx",sheet=1)
# 抽取数据
df1 <- df[,3:8]
(3)使用apply()函数计算平均分,然后使用length()函数和mean()函数统计各科成绩大于平均分的人数,代码如下:
# 各科成绩平均分 mean1 <- apply(df1, 2, mean) # 统计各科成绩大于平均分的学生人数 x1=paste(length(df1$语文[df1$语文>mean(df1$语文)]),"人") x2=paste(length(df1$数学[df1$数学>mean(df1$数学)]),"人") x3=paste(length(df1$英语[df1$英语>mean(df1$英语)]),"人") x4=paste(length(df1$物理[df1$物理>mean(df1$物理)]),"人") x5=paste(length(df1$化学[df1$化学>mean(df1$化学)]),"人") x6=paste(length(df1$生物[df1$生物>mean(df1$生物)]),"人")
(4)使用barplot()函数绘制柱形图,代码如下:
# 绘制柱形图
p=barplot(mean1, # 柱子高度
ylim=c(0,150), # y 轴范围
ylab = "平均分") # y 轴标签
# 添加文本标签
text(p,mean1+5,labels=c(x1,x2,x3,x4,x5,x6))
运行程序,结果如图1.31所示。
图1.31 柱形图分析各科中上等学生人数
从运行结果得知:通过查看前面数据得知有58名学生,那么基本上各科中上等学生均占到了一半。
根据某高中班级考试情况,语数英考试成绩按位次由高到低分为A、B、C、D、E五个等级。各等级人数所占比例依次为:A等级15%,B等级30%,C等级30%,D、E等级共25%,E等级为不合格。首先通过quantile()函数获取各个等级的分数,然后使用cut()函数按分数段分割数据并标记等级,最后按等级统计人数并绘制饼形图。实现过程如下(源码位置:资源包\Code\01\level_data.R)。
(1)在项目文件夹下新建一个R脚本文件,命名为level_data.R。
(2)使用openxlsx包的read.xlsx()函数读取Excel文件,代码如下:
# 加载程序包
library(openxlsx)
library(dplyr)
# 读取Excel 文件
df <- read.xlsx("学生成绩统计分析/成绩表 1.xlsx",sheet=1)
(3)通过quantile()函数获取各个等级的分数,代码如下:
a <- quantile(df$语文,probs = c(0.15, 0.3,0.75,0.9,1)) a b <- quantile(df$数学,probs = c(0.15, 0.3,0.75,0.9,1)) b c <- quantile(df$英语,probs = c(0.15, 0.3,0.75,0.9,1)) c
(4)使用cut()函数按分数段分割数据并标记等级,代码如下:
# 按分数段分割数据并标记等级
df$语文等级 <- cut(df$语文,breaks=c(-Inf, 90, 95,101,106,Inf),
labels = c("E","D","C","B","A"), right=FALSE)
df$数学等级 <- cut(df$数学,breaks=c(-Inf, 69,77,99, 109,Inf),
labels = c("E","D","C","B","A"), right=FALSE)
df$英语等级 <- cut(df$英语,breaks=c(-Inf, 69,79,98, 103, Inf),
labels = c("E","D","C","B","A"), right=FALSE)
(5)使用summarise()函数结合group_by()函数实现按等级统计人数,代码如下:
# 统计各等级人数 df1<- summarise(group_by(df,语文等级),人数=length(语文等级)) df2<- summarise(group_by(df,数学等级),人数=length(数学等级)) df3<- summarise(group_by(df,英语等级),人数=length(英语等级))
(6)获取人数、设置饼形图颜色和计算百分比,然后创建1行3列的绘图区域,最后绘制饼形图,代码如下:
# 获取人数 x1 = df1$人数 x2 = df2$人数 x3 = df3$人数 # 饼形图颜色 mycolors1 <- topo.colors(5) # 计算百分比 pct1 <- paste(round(100*x1/sum(x1), 1), "%") pct2 <- paste(round(100*x2/sum(x2), 1), "%") pct3 <- paste(round(100*x3/sum(x3), 1), "%") # 创建 1 行 3 列的绘图区域 par(mfrow = c(1,3)) # 绘制饼形图 pie(x1,labels = paste(df1$语文等级,pct1),col=mycolors1) pie(x2,labels = paste(df2$数学等级,pct2),col=mycolors1) pie(x3,labels = paste(df3$英语等级,pct3),col=mycolors1)
运行程序,结果如图1.32所示。
图1.32 饼形图分析语数英成绩等级状况
成绩波动情况分析,主要通过学生的8次测试成绩排名来分析学生成绩的波动幅度,从而得到成绩从稳定到不稳定的学生名单。首先使用apply()函数计算8次测试成绩的标准差,然后使用sort()函数按标准差升序排序,实现过程如下(源码位置:资源包\Code\01\fluctuate_data.R):
(1)在项目文件夹下新建一个R脚本文件,命名为fluctuate_data.R。
(2)使用openxlsx包的read.xlsx()函数读取Excel文件,代码如下:
# 加载 openxlsx 包
library(openxlsx)
# 读取Excel 文件
df <- read.xlsx("学生成绩统计分析/测试成绩.xlsx",sheet=1)
(3)通过计算8次测试成绩的标准差得到波动幅度,然后使用sort()函数按照标准差升序排序,代码如下:
# 波动幅度 df['标准差'] <- apply(df[,4:10],1,sd) # 按照标准差升序排序 View(df[order(df[,"标准差"]),])
运行程序,结果如图1.33所示。
图1.33 按照标准差升序排序
从运行结果得知:标准差越小发挥越稳定,例如排名第1和第9的学生发挥最为稳定。
通过1.7.7节我们得到了学生成绩的波动情况和名单,接下来看一下排名第1的学生8次测试成绩排名和升降情况。首先使用subset()函数检索“名次”等于1的数据,然后创建2行1列的绘图区域,使用plot()函数分别绘制测试成绩排名折线图和排名升降折线图,其中排名升降折线图应使用diff()函数计算差分,也就是计算本次排名与上一次排名的差分。实现过程如下(源码位置:资源包\Code\01\TOP1_data.R)。
(1)在项目文件夹下新建一个R脚本文件,命名为TOP1_data.R。
(2)使用openxlsx包的read.xlsx()函数读取Excel文件,代码如下:
# 加载 openxlsx 包
library(openxlsx)
# 读取Excel 文件
df <- read.xlsx("学生成绩统计分析/测试成绩.xlsx",sheet=1)
(3)使用subset()函数筛选名次等于1的数据并使用t()函数实现行列转置,代码如下:
# 筛选名次等于 1 的数据 df <- subset(df,名次==1) # 行列转置 df1 <- t(df[,4:11])
(4)绘制测试成绩排名折线图,代码如下:
# x 轴和 y 轴数据 x1 <- names(df1[,1]) y1 <- df1 # 创建 2 行 1 列的绘图区域 par(mfrow = c(2,1)) # 绘制测试成绩排名折线图 plot(y1,type="l",lwd=2,col="blue",xlab="",ylab="测试成绩排名",xaxt="n",ylim = c(0,100)) # 添加标记 points(y1,pch=21,bg=2) # 设置 x 轴标签 axis(side=1,at=1:8,labels=x1)
(5)绘制排名升降折线图,代码如下:
# 使用 diff()函数计算差分 y2=diff(df1) #x 轴数据 x2 <- names(df1[-1,1]) # 绘制排名升降折线图 plot(y2,type="l",lwd=2,col="red",xlab="",xaxt="n",ylab="排名升降情况") # 添加标记 points(y2,pch=21,bg=2) # 设置 x 轴标签 axis(side=1,at=1:7,labels=x2)
运行程序,结果如图1.34所示。
图1.34 折线图分析TOP1学生测试成绩和排名升降情况