本次实验,完成后你将掌握:
Rpractice总工程,读取上一次实验清洗完成的数据集output文件夹data/disaster_data_cleaned.xlsx清洗数据集%>%、分组group_by、summarise汇总本次实验继续复用Rpractice总工程,不需要新建RStudio项目。
- code/:保存本次Rmd脚本,命名
labB_visualization.Rmd- data/:读取实验A产出的清洗后数据 disaster_data_cleaned.xlsx
- output/:本次所有绘图,全部导出保存到这里
课堂操作步骤: 1. 双击打开 Rpractice.Rproj 2. File → New
File → R Script,保存到code文件夹,命名labB_visualization.R
3.
读取上节课清洗好的数据:read_xlsx("data/disaster_data_cleaned.xlsx")
数据表达三大形式:文字表达、表格表达、图形表达。 表达的目的:简化信息、探索模式、辅助决策、讲述数据故事。
分组统计不同灾害的事件数量、伤亡合计、经济损失合计,生成汇报用表格。
library(tidyverse)
library(knitr)
disaster_clean <- readxl::read_xlsx("data/disaster_data_cleaned.xlsx")
simple_summary <- disaster_clean %>%
# group_by:按照灾害类型分组;Tidy Data下分组只需要指定列名,非常方便
group_by(disaster_type) %>%
# summarise:分组汇总计算新指标
summarise(
事件次数 = n(), # n():统计每组观测行数
伤亡人数 = sum(casualties, na.rm = TRUE), # sum求和,na.rm=TRUE:计算时忽略NA
经济损失_百万美元 = round(sum(economic_loss, na.rm = TRUE), 1), # round保留1位小数
) %>%
arrange(desc(伤亡人数)) %>% # arrange排序:desc代表降序
mutate(
伤亡人数 = format(伤亡人数, big.mark = ","), # 数字千分位分隔符,美化输出
经济损失_百万美元 = format(经济损失_百万美元, big.mark = ",")
)
kable(simple_summary,
col.names = c("灾害类型", "事件次数", "伤亡人数", "经济损失(百万美元)"),
caption = "2030年灾害事件影响分析",
align = c("l", "r", "r", "r"),
format = "simple")
| 灾害类型 | 事件次数 | 伤亡人数 | 经济损失(百万美元) |
|---|---|---|---|
| earthquake | 6 | 778 | 20,817.0 |
| flood | 8 | 215 | 11,960.0 |
| drought | 1 | 126 | 1,250.0 |
| typhoon | 6 | 106 | 14,088.2 |
分为两大类:①基于原始观测;②基于统计汇总。所有图片导出保存至Rpractice工程
output/。
set.seed(123)
# 生成30个考试分数,均值75标准差10
exam_scores <- round(rnorm(30, mean = 75, sd = 10))
# pmax/pmin:限制分数在0~100之间,防止超出合理范围
exam_scores <- pmax(0, pmin(100, exam_scores))
# stem:绘制茎叶图,原生R函数,适合少量样本
stem(exam_scores)
##
## The decimal point is 1 digit(s) to the right of the |
##
## 5 | 58
## 6 | 244
## 6 | 588999
## 7 | 0133
## 7 | 666799
## 8 | 0023
## 8 | 78
## 9 | 123
set.seed(2026)
# 生成通勤时间数据
commute_time <- round(rlnorm(200, meanlog = 3.6, sdlog = 0.5))
stripchart(commute_time,
method = "jitter", # jitter:点抖动,避免点重叠
pch = 16, # pch:点样式,16是实心圆点
col = rgb(0,0,0,0.4),# 设置颜色和透明度
xlab = "每日通勤时间 (分钟)", # X轴标签
main = "城市白领通勤时间分布云图") # 图标题
grid(nx = 20, col = "gray", lty = "dotted") # 添加网格线
set.seed(2026)
work_years <- rep(1:15,2) # 工作年限,重复1~15两遍
salary <- work_years*1 + runif(30,-3,3) # 月薪,增加随机扰动
salary[3] <- 12
df_scatter <- data.frame(work_years, salary)
library(ggplot2)
# ggplot绘图:第一个参数是数据集,aes()映射x,y等美学变量,Tidy Data直接映射列名
p_scatter <- ggplot(df_scatter,aes(x=work_years,y=salary))+
geom_point(size=3,alpha=0.7,color="grey30")+ # 绘制点图层
labs(x="工作年限(年)",y="月薪(千元)",title="工作年限与月薪的关系")+ # 设置坐标轴与标题
theme_minimal() # 主题:简约白底风格
ggsave("output/scatter_work_salary.png", plot=p_scatter, width=7, height=4, dpi=300)
print(p_scatter) # 在html文档中输出图片
set.seed(2026)
# 构造月度销售数据
df_line <- tibble(
month = 1:12,
sales = 200 + seq(0,50,length.out=12)+rnorm(12,0,5)
)
p_line <- ggplot(df_line, aes(x=month,y=sales))+
geom_line(size=1,color="#2c7bb6")+ # 绘制折线图层
geom_point(size=3,color="#2c7bb6")+# 叠加数据点
scale_x_continuous(breaks=1:12)+ # X轴刻度1到12月
labs(title="某公司月度销售额变化趋势",x="月份",y="销售额(万元)")+
theme_minimal()+
theme(plot.title = element_text(face="bold"))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
ggsave("output/line_sales.png", plot=p_line, width=7, height=4, dpi=300)
print(p_line)
set.seed(2026)
df_edu <- tibble(
education = sample(c("本科","硕士","高中及以下","大专"),
size=400, replace = TRUE,
prob=c(0.5,0.25,0.125,0.125))
) %>%
count(education) %>% # count统计各类别数量,Tidy Data常用快速计数函数
mutate(percentage = n/sum(n)) # 新增百分比列
p_pie <- ggplot(df_edu, aes(x="", y=percentage, fill=education))+
geom_col(width=1,color="white")+
coord_polar("y")+ # 极坐标转换,把条形图变成饼图
scale_fill_brewer(palette = "Spectral")+
labs(title="受访者学历构成调查", fill="学历层次")+
theme_void() # 清空坐标轴,饼图不需要坐标轴
ggsave("output/pie_edu.png", plot=p_pie, width=6, height=6, dpi=300)
print(p_pie)
set.seed(2026)
df_community <- tibble(
district = rep(c("A街道","B街道","C街道","D街道","E街道"),each=50),
borrowed = c(rnorm(50,500,20), rnorm(50,450,20), rnorm(50,400,20),
rnorm(50,350,20), rnorm(50,300,20))
) %>%
group_by(district) %>%
summarise(avg_borrowed = mean(borrowed)) # 分组求均值
p_bar <- ggplot(df_community, aes(x=district,y=avg_borrowed, fill=district))+
geom_col(alpha=0.8, width=0.6)+
scale_fill_brewer(palette="Blues")+
labs(title="各街道社区平均图书借阅量",x="社区街道",y="平均借阅量(本)")+
theme_minimal()+
theme(legend.position="none") # 隐藏图例,x轴已经标注类别
ggsave("output/bar_community.png", plot=p_bar, width=7, height=4, dpi=300)
print(p_bar)
set.seed(2026)
df_policy <- tibble(
type = c(rep("本地户籍",100), rep("非本地户籍",100)),
attitude = c(rep("满意",80),rep("不满意",20),rep("满意",30),rep("不满意",70))
) %>%
count(type, attitude) # 按两个变量交叉计数
p_gbar <- ggplot(df_policy, aes(x=type,y=n,fill=attitude))+
geom_col(position = position_dodge(width=0.8), width=0.7)+ # position_dodge:分组并列
scale_fill_manual(values = c("满意"="forestgreen","不满意"="firebrick"))+
labs(title="不同户籍群体对政策的满意度分布",x="户籍类型",y="受访人数(人)",fill="态度")+
theme_minimal()
ggsave("output/groupbar_policy.png", plot=p_gbar, width=7, height=4, dpi=300)
print(p_gbar)
set.seed(2026)
df_commute <- tibble(
group = rep(c("企业职员","公务人员","自由职业"),each=40),
minutes = c(rnorm(40,40,10), rnorm(40,35,10), rnorm(40,40,20))
)
df_commute$minutes[df_commute$group=="企业职员"][1] <-120 # 手动添加一个极端异常点
p_box <- ggplot(df_commute, aes(x=group,y=minutes,fill=group))+
geom_boxplot(alpha=0.6, outlier.color="red")+ # outlier.color:异常点标红
scale_fill_brewer(palette="Set2")+
labs(title="不同职业群体日均通勤时间",x="职业群体",y="时间(分钟)",fill="职业")+
theme_minimal()+
theme(legend.position="none")
ggsave("output/boxplot_commute.png", plot=p_box, width=7, height=4, dpi=300)
print(p_box)
set.seed(2026)
# 生成幸福感得分
df_happy <- tibble(score = rnorm(1000, mean=60, sd=15))
p_hist <- ggplot(df_happy, aes(x=score))+
geom_histogram(aes(y=after_stat(density)), binwidth=5, fill="orange",color="white",alpha=0.8)+
stat_function(fun=dnorm, args=list(mean=60,sd=15),color="darkblue",size=1)+ # 添加理论正态曲线
labs(title="居民主观幸福感得分分布",x="幸福感量表得分(0‑100)",y="概率密度")+
theme_minimal()
ggsave("output/hist_happy.png", plot=p_hist, width=7, height=4, dpi=300)
print(p_hist)
随堂练习:
summarise()可以快速制作统计汇总表,kable输出美观表格用于报告。disaster_data_cleaned.xlsx,按disaster_type分组,计算每种灾害的平均经济损失,用kable输出汇总表。severity_level严重等级下伤亡人数casualties。