购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.7 数据统计分析

1.7.1 综合排名

综合排名包括各科成绩排名以及语文、数学、英语总分排名和总分排名,实现过程如下(源码位置:资源包\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

1.7.2 直方图分析各科成绩

通过绘制各科成绩直方图查看各科成绩的分布情况,主要使用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

从运行结果得知:“数学”成绩呈右偏态分布,即直方图右侧缺失,说明高分段学生缺失,试卷有难度。其他学科呈左偏态分布,即直方图左侧缺失,说明低分段学生较少,试卷难度适中。

说明

负偏态分布,也称为左偏态,指的是在一个不对称或偏斜的次数分布中,次数分布的高峰偏右,而长尾则从右逐渐延伸于左端。这种分布的特点是偏态系数小于零,意味着众数位于较大分数或量数的一侧(右侧),而长尾则位于较小分数或量数的一侧(左侧)。在学生的学业成绩分布中,负偏态分布表明高分人数很多,低分人数很少,这通常意味着测试的难度较低,考试要求低于教学要求,或者学生的基础较好。因此,当学生成绩呈现负偏态分布时,说明测验的整体难度相对偏易。

此外,负偏态分布的原因可能包括试题难度过小,导致部分学生成绩过高,从而使总分的分布呈现负偏态。这种情况下,测验的整体难度被认为是正常的。然而,需要注意的是,负偏态分布并不总是意味着测验难度过低,它也可能反映试题难度介于过大和过小之间,导致一部分学生不能正常发挥。因此,在解释负偏态分布时,需要综合考虑试题的难度设置和学生的实际表现。

1.7.3 箱形图分析各科成绩

通过绘制箱形图分析各科成绩,主要使用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 箱形图分析各科成绩

1.7.4 各科最高分和最低分状况分析

对各科最高分和最低分状况进行分析时,首先使用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 柱形图分析各科最高分和最低分状况

从运行结果得知:除了语文,其他各科成绩最高分和最低分差距还是比较大的。

1.7.5 各科中上等成绩统计分析

各科中上等成绩统计分析,主要统计各科成绩超过平均分的人数。通常来讲,如果学生的成绩在班级里达到或超过了平均分,那么其基本就属于中上等学生,即使是在平均分上下,不是幅度相差太大都可以算得上是中上等学生。例如,一个班级有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名学生,那么基本上各科中上等学生均占到了一半。

1.7.6 语数英成绩等级状况分析

根据某高中班级考试情况,语数英考试成绩按位次由高到低分为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 饼形图分析语数英成绩等级状况

1.7.7 成绩波动情况分析

成绩波动情况分析,主要通过学生的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.8 个人成绩排名分析

通过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学生测试成绩和排名升降情况 vFqP5W6Sc6WJLEOLebXs5vcwcwtkn4Fqsr2vT6BDuUZpPp+E68jhOV45xW60/hYN

点击中间区域
呼出菜单
上一章
目录
下一章
×