#数据准备
data <- read.csv("F:/数据可视化/期末报告/courses.csv", stringsAsFactors = FALSE, fileEncoding = "UTF-8")
df<-data |>
select(Category,Enrolled_Students) |>
summarise(n=sum(Enrolled_Students),.by=Category) |>
rename(类别=Category,人数=n ) |>
arrange(desc(人数)) |>
mutate(累积百分比 = cumsum(人数*100/sum(人数)), #计算累积百分比
累积百分比 = round(累积百分比,1), #保留一位小数
类别 = fct_inorder(类别) #按字符出现顺序定义因子水平
)
datatable(df,rownames = FALSE)数据可视化期末报告
1 报告要求
期末实验报告由5章节5个图形组成,每个章节需要作一个图形。
每个章节选择作什么图自主选择,作图前补充完整图形标题名称,例如:图形1——多变量条形图。
案例数据自主收集,不同章节可以公用一个数据集。但同学间不允许使用相同数据集。
每个章节的数据集合需要通过
datatable函数展示,并简要解释数据来源和变量意义。每个输出图形后需要对图形作简要解读,最少需针对图形提出一个观点。
渲染html文件保留代码展示,6月22日前将发布网址提交至共享文档
“8、期末报告”列中。评分标准:
每章节图形各20分
能有效输出图形和合理解释75%
数据独特性强10%
图形个性化强15%
2 类别数据可视化
2.1 案例数据解释与展示
该course数据集包含课程信息,有课程ID、课程类目、课程总时长、课程章节数量、报名人数、完课率、课程发布平台数量、课程价格、课程评价、考试平均得分等属性,可用于方案决策、属性分析、聚类、预测等研究。
数据集属性说明如下:
Course_ID:课程ID
Category:课程类目(类别)
Duration (hours):课程总时长
Chapter_Number:课程章节数量
Enrolled_Students:报名人数(人数)
Completion_Rate (%):完课率
Platform_Number:课程发布平台数量
Price (¥):课程价格
Course_Evaluation:课程评价(5分制)
Examination_Average_Score:考试平均得分
2.2 图形1——帕累托图
按学生人数排序的课程类别柱状图
红色累积百分比曲线
双Y轴显示绝对人数和相对百分比
自动适应的颜色和标签
# 创建帕累托图
pareto <- ggplot(df, aes(x = 类别)) +
# 柱状图(人数)
geom_col(aes(y = 人数, fill = 类别),
width = 0.7, alpha = 0.8) +
# 折线图(累积百分比)
geom_line(aes(y = 累积百分比 * max(人数)/100, group = 1),
color = "red", linewidth = 1) +
# 点图(累积百分比)
geom_point(aes(y = 累积百分比 * max(人数)/100),
color = "red", size = 3) +
# 添加累积百分比标签
geom_text(aes(y = 累积百分比 * max(人数)/100,
label = paste0(累积百分比, "%")),
vjust = -1, color = "red", size = 3.5) +
# 添加人数标签
geom_text(aes(y = 人数, label = 人数),
vjust = -0.5, size = 3) +
# 双Y轴设置
scale_y_continuous(
name = "学生人数",
sec.axis = sec_axis(~ ./(max(df$人数)/100),
name = "累积百分比(%)")
) +
# 颜色和主题设置
scale_fill_brewer(palette = "Set3") +
labs(title = "课程类别学生人数帕累托图",
x = "课程类别") +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
legend.position = "none",
panel.grid.major = element_line(color = "gray90"),
panel.grid.minor = element_blank()
)
# 显示图形
pareto2.3 心得体会:
数据准备:
需要先对数据进行排序,按学生人数降序排列
计算累积百分比是创建帕累托图的关键步骤
双Y轴处理:
通过
scale_y_continuous()和sec_axis()实现了主次双Y轴,这是帕累托图的核心且使用
twinx()创建第二个Y轴用于百分比心得:理解这种转换关系是创建双轴图表的关键,需要确保两个轴的数值范围匹配
图层叠加的艺术:
scale_fill_brewer(palette = "Set3")提供了专业的配色方案代码通过叠加多个几何对象(
geom_col,geom_line,geom_point)构建完整图表每个几何对象都有明确的用途:柱状图展示原始数据,折线和点图展示累积百分比
格式化挑战:
科学计数法转换需要特别处理
通过
vjust参数微调标签位置避免重叠可读性优化:
使用
geom_text添加了两类标签:人数值和百分比值旋转x轴标签避免重叠
控制标注密度,避免图表过于拥挤
2.4 图表特点分析:
图表类型:这是一个帕累托图(Pareto Chart),用于显示不同课程类别的学生人数分布情况,并展示累积百分比。
数据特点:
显示了多个课程类别的学生人数,最高约375,326人,最低约75人
包含累积百分比线,最高达到81.2%
各柱形高度差异显著,表明学生人数在不同课程类别间分布不均
3 数据分布可视化
3.1 案例数据解释与展示
该online_courses数据集是941门在线课程的信息,信息内容含有课程ID、名称、类别、持续时间、注册、完成率、上线平台、价格和评价排名等属性。它提供了4个平台和各种课程类别的数据,可用于分析在线学习趋势、比较平台、可视化报告和构建预测模型。
数据内容说明:
Course_ID:课程ID
Course_Name:课程名称
Category:课程类目
Duration (hours):课程持续时长
Enrolled_Students:报名学生人数
Completion_Rate (%):完课率
Platform:课程上线平台
Price ($):课程价格
Rank:课程排名
data <- read.csv("F:/数据可视化/期末报告/online_courses.csv", stringsAsFactors = FALSE, fileEncoding = "UTF-8")
datatable(data)data$Enrolled_Students <- as.numeric(as.character(data$Enrolled_Students))3.2 图形2——单变量直方图(Enrolled_Students:报名学生人数)
# 加载必要的包
library(ggplot2)
library(e1071) # 用于计算偏度和峰度
library(scales) # 用于格式化坐标轴
# 自定义主题
mytheme <- theme_bw() +
theme(
plot.title = element_text(size = 16, hjust = 0.5),
axis.title = element_text(size = 14),
axis.text = element_text(size = 12),
legend.position = "top",
legend.title = element_blank(),
panel.grid.major = element_line(color = "grey80", linetype = "dashed"),
panel.grid.minor = element_blank()
)
# 计算统计量
mean_val <- mean(data$Enrolled_Students, na.rm = TRUE)
median_val <- median(data$Enrolled_Students, na.rm = TRUE)
skewness_val <- skewness(data$Enrolled_Students, na.rm = TRUE)
kurtosis_val <- kurtosis(data$Enrolled_Students, na.rm = TRUE)
# 创建直方图
ggplot(data, aes(x = Enrolled_Students)) +
geom_histogram(aes(y = ..density..),
bins = 30,
fill = "steelblue",
color = "white",
alpha = 0.7) +
geom_density(color = "red", size = 1) + # 核密度曲线
geom_rug(sides = "b", color = "darkgreen", alpha = 0.5) + # 地毯图
geom_vline(xintercept = mean_val,
color = "blue",
linetype = "dashed",
size = 1) + # 均值参考线
geom_point(aes(x = median_val, y = 0),
color = "purple",
size = 3) + # 中位数参考点
annotate("text",
x = median_val,
y = 0.0001,
label = paste("Median:", round(median_val, 1)),
color = "purple",
vjust = -1) + # 中位数注释
annotate("text",
x = Inf, y = Inf,
label = paste("偏度Skewness:", round(skewness_val, 2)),
hjust = 1.1, vjust = 2,
color = "black") + # 偏度注释
annotate("text",
x = Inf, y = Inf,
label = paste("峰度Kurtosis:", round(kurtosis_val, 2)),
hjust = 1.1, vjust = 4,
color = "black") + # 峰度注释
scale_x_continuous(labels = comma) + # 格式化x轴标签
labs(title = "报名学生人数分布直方图",
x = "报名学生人数",
y = "学生人数分布密度") +
mytheme3.3 图形解读
该直方图展示了学生注册人数的分布情况,从图形可以得出以下关键信息:
数据呈现近似正态分布,注册人数主要集中在3,000-4,000区间,峰值密度约6e-04;
偏度系数0.16显示分布略微右偏,峰度系数2.46表明数据分布比正态分布更平缓,尾部较薄。学生人数集中在中间范围,极端值(极高或极低注册人数的课程)较少。
值和中位数(3354)位置接近,约50%的课程注册人数≤3354人,另一半≥3354人,进一步验证了分布的对称性;
最高密度出现在 3,000–4,000人 区间(参考x轴标注),说明大多数课程的注册人数在此范围内。
地毯图显示在2000-5000区间有少量极端值,但整体数据集中;
科学计数法的y轴标签和千位分隔符的x轴标签使大数字阅读更清晰。
3.4 代码心得体会
根据ggplot2代码通过多层叠加实现了专业统计可视化:
密度直方图:
geom_histogram(aes(y=..density..))将频数转换为密度,使不同样本量的数据可比核密度曲线:
geom_density()完美叠加在直方图上,直观展示数据分布的平滑形态地毯图:
geom_rug()在坐标轴边缘显示原始数据点,有效补充分布细节
统计量标注:通过
annotate()添加的偏度(0.16)和峰度(2.46)数值,快速判断分布形态参考线/点:
geom_vline()和geom_point()标记的均值和中位数(3354),直观显示数据集中趋势自动计算:
e1071包的skewness()和kurtosis()函数简化了统计量计算过程
4 变量关系可视化
4.1 案例数据解释与展示
data <- read.csv("F:/数据可视化/期末报告/online_courses.csv", stringsAsFactors = FALSE, fileEncoding = "UTF-8")
datatable(data)4.2 图形3——在线课程持续时间与完成率关系散点图
# 数据预处理
# 将Duration (hours)转换为数值型
data$Duration..hours. <- as.numeric(data$Duration..hours.)
# 将Completion_Rate转换为数值型(处理百分号)
data$Completion_Rate <- as.numeric(gsub("%", "", data$Completion_Rate))
# 检查转换结果
str(data)'data.frame': 941 obs. of 10 variables:
$ Course_ID : int 520 503 751 72 800 544 586 347 162 602 ...
$ Course_Name : chr "Course_520" "Course_503" "Course_751" "Course_72" ...
$ Category : chr "Business" "Business" "Data Science" "Data Science" ...
$ Duration..hours. : num 40 40 40 40 40 40 40 40 40 40 ...
$ Enrolled_Students : int 4113 2541 3220 4176 4563 2769 3381 3535 3685 2284 ...
$ Completion_Rate....: num 84.4 73.4 77.7 88.3 92.3 ...
$ Platform : chr "LinkedIn Learning" "LinkedIn Learning" "Udemy" "Coursera" ...
$ Price.... : num 74.7 97.2 67.5 88.9 72.9 ...
$ Rank : num 4.91 4.2 4.36 4.66 4.85 ...
$ Completion_Rate : num 84.4 73.4 77.7 88.3 92.3 ...
summary(data[c("Duration..hours.", "Completion_Rate")]) Duration..hours. Completion_Rate
Min. : 40.00 Min. :70.01
1st Qu.: 62.00 1st Qu.:77.88
Median : 77.00 Median :83.79
Mean : 74.36 Mean :84.19
3rd Qu.: 89.00 3rd Qu.:89.66
Max. :100.00 Max. :99.99
# 3. 绘制散点图
scatter_plot <- ggplot(data, aes(x = Duration..hours., y = Completion_Rate)) +
geom_point(color = "#3498db", size = 3, alpha = 0.7) + # 使用蓝色点
geom_smooth(method = "lm", se = FALSE, color = "#e74c3c") + # 添加趋势线
labs(title = "在线课程持续时间与完成率关系",
subtitle = "数据来源:online_courses.csv",
x = "课程持续时间 (小时)",
y = "课程完成率 (%)",
caption = "注:完成率已转换为百分比数值") +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, size = 16, face = "bold"),
plot.subtitle = element_text(hjust = 0.5, color = "gray50"),
axis.title = element_text(size = 12),
panel.grid.major = element_line(color = "gray90"),
panel.grid.minor = element_blank()
)
# 显示散点图
print(scatter_plot)4.3 图表含义
该散点图展示了在线课程持续时间(小时)与课程完成率(%)之间的关系,旨在分析课程时长是否影响学习者的完成率
X轴:课程持续时间(小时),数值型变量
Y轴:课程完成率(%),数值型变量(已去除百分号转换)
蓝色点:每个点代表一门课程,横纵坐标分别对应其持续时间和完成率
红色趋势线:采用线性回归(
method = "lm")拟合数据,反映两变量的整体相关性
4.4 心得体会:
4.4.0.1 1、数据特点
变量转换:
Duration (hours)→as.numeric(确保数值计算正确);Completion_Rate→ 去除百分号后转换为数值(如”85%” →85)数据检查:
str(data)验证变量类型转换是否成功;summary()查看两变量的分布(最小值、最大值、中位数等)点的分布:
若点呈右上趋势(趋势线斜率为正),说明课程时间越长,完成率可能越高(学习者更愿意完成长期课程)。
若点呈右下趋势(斜率为负),则短期课程的完成率更高(学习者可能因时间投入少更易坚持)。
若点无明显趋势(趋势线接近水平),则两者无显著关联。
异常值:
偏离趋势线的点(如某门课程时间短但完成率极低)可能需进一步分析原因(如课程难度、内容质量)。
5 样本相似性可视化
5.1 案例数据解释与展示
data <- read.csv("F:/数据可视化/期末报告/online_courses.csv", stringsAsFactors = FALSE, fileEncoding = "UTF-8")
datatable(data)5.2 图形4——不同平台在线课程指标对比(雷达图)
# 加载必要的库
library(ggiraphExtra)
library(ggplot2)
library(dplyr)
library(tidyr)
# 读取数据
data <- read.csv("online_courses.csv")
# 选择需要分析的数值型变量(排除非数值型变量和ID类变量)
numeric_vars <- data %>%
select(Duration..hours., Enrolled_Students, Completion_Rate...., Price...., Rank) %>%
names()
# 按Platform分组计算均值
radar_data <- data %>%
group_by(Platform) %>%
summarise(across(all_of(numeric_vars), mean, na.rm = TRUE)) # 修正括号
# 绘制雷达图
ggRadar(
data = radar_data,
aes(group = Platform),
interactive = FALSE, # 设置为TRUE可生成交互式图形
rescale = TRUE, # 将各变量缩放到相同范围
legend.position = "right",
size = 1,
alpha = 0.3
) +
labs(title = "不同平台在线课程指标对比(雷达图)",
caption = "数据来源:online_courses.csv") +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
legend.text = element_text(size = 8) # 修正为英文括号
)5.3 图形解析:
5.3.1 1. 学生报名情况(Enrolled_Students)
Coursera:注册人数表现突出,可能是由于平台知名度高、课程种类丰富
Udemy:注册人数次之,反映其大众化定价策略和广泛课程覆盖的优势
LinkedIn Learning:注册人数中等,与其职业导向的垂直用户群体特征相符
edX:注册人数相对较低,可能因其更专注高等教育和认证课程
报名趋势:Coursera > Udemy > LinkedIn Learning > edX
5.3.2 2. 课程完成率(Completion_Rate)
LinkedIn Learning:完成率最高,可能与职场用户的学习目的性强有关
Coursera:完成率次之,得益于其结构化课程设计和证书激励
edX:完成率中等,部分用户可能只旁听不追求完课
Udemy:完成率最低,或因用户多为碎片化学习,缺乏强制进度
完成率趋势:LinkedIn Learning > Coursera > edX > Udemy
5.4 心得体会:
- 数据可视化是数据分析的利器
雷达图能直观展示多维度的平台对比,一眼就能看出Coursera在注册人数上的绝对优势和LinkedIn Learning在完成率上的突出表现
通过图形化呈现,复杂的多维数据比较变得简单易懂,这是纯数字表格无法实现的
- 数据清洗和预处理至关重要
原始数据中的变量名包含特殊符号(如..),需要规范处理
对缺失值(na.rm=TRUE)的处理保证了分析的准确性
分组计算均值前确认数据类型是数值型,避免了分析错误
- 选择合适的图表类型很关键
雷达图特别适合比较3个以上平台在5-6个维度的表现
通过rescale=TRUE参数自动标准化不同量纲的指标,使比较更合理
交互式选项(interactive)为后续深度探索提供了可能
6 时间序列可视化
6.1 案例数据解释与展示
data <- read.csv("F:/数据可视化/期末报告/shanghai_index_2024.csv", stringsAsFactors = FALSE, fileEncoding = "UTF-8")
datatable(data)6.2 图形5——上海指数价格走势(按成交额区间分面图)
library(ggplot2)
library(dplyr)
library(scales)
data <- read.csv("shanghai_index_2024.csv") %>%
mutate(
日期 = as.Date(日期),
成交额区间 = cut(
成交额,
breaks = quantile(成交额, probs = seq(0, 1, 0.25), na.rm = TRUE),
labels = c("低", "中低", "中高", "高"),
include.lowest = TRUE
)
)
ggplot(data, aes(x = 日期)) +
geom_area(aes(y = 收盘, fill = "收盘价"), alpha = 0.6) +
geom_area(aes(y = 开盘, fill = "开盘价"), alpha = 0.6) +
geom_area(aes(y = 最高, fill = "最高价"), alpha = 0.4) +
geom_area(aes(y = 最低, fill = "最低价"), alpha = 0.4) +
facet_wrap(
~成交额区间,
ncol = 2,
labeller = labeller(成交额区间 = function(x) paste("成交额:", x))
) +
scale_fill_manual(
values = c("开盘价" = "#4DAF4A", "收盘价" = "#377EB8", "最高价" = "#E41A1C", "最低价" = "#984EA3"),
name = "价格类型"
) +
scale_y_continuous(labels = comma) +
labs(title = "上海指数价格走势(按成交额区间分面图)", x = "日期", y = "价格") +
theme_minimal() +
theme(
legend.position = "bottom",
plot.title = element_text(hjust = 0.5, face = "bold"),
axis.text.x = element_text(angle = 45, hjust = 1, size = 8),
strip.text = element_text(face = "bold") # 分面标题加粗
)6.3 图片解读:
分面布局:
按 成交额区间 分面显示(低、中低、中高、高),共4个子图。
每个子图显示 开盘价、收盘价、最高价、最低价 的叠加面积图。
Y轴(价格):
价格范围在 0-3,000 之间。
使用了
scales::comma格式化数字(如3,000)。X轴(日期):
横轴显示 2024年1月 至 2025年12月 的日期。
标签可能存在重叠(如“1月 2024”重复出现),需优化。
6.4 心得体会:
6.4.1 1. 数据预处理:稳健性优先
关键点:
列名检查:确保CSV列名与代码中的变量名完全一致(如
成交额vs成交额,避免中英文混用)。日期格式化:用
as.Date()统一日期格式,避免后续绘图时X轴解析错误。分组逻辑:使用
cut()+quantile()分组时,务必加na.rm = TRUE处理缺失值。
6.4.2 2. 可视化设计:图层叠加与分面技巧
关键点:
面积图叠加:通过
geom_area()的alpha参数控制透明度,避免完全遮挡。分面优化:
facet_wrap()的scales = "free_y"允许Y轴自适应,避免比例扭曲。颜色映射:将颜色映射到分类变量(如
fill = "开盘价"),而非硬编码。