ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

用 R 与 ggplot2 讲好一个数据故事:Data Science for Beginners 线图、散点图与条形图作业实战解析

用 R 与 ggplot2 讲好一个数据故事:Data Science for Beginners 线图、散点图与条形图作业实战解析 用 R 与 ggplot2 讲好一个数据故事Data Science for Beginners 线图、散点图与条形图作业实战解析【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners本指南围绕 Data-Science-For-Beginners 课程第 09 课R 版本的课后作业展开在明尼苏达州鸟类数据集data/birds.csv中针对某一种特定鸟类深入挖掘数据并运用本课学过的线图、散点图与条形图三种图表类型在 notebook 中构建一个完整的数据叙事。读完本文你将掌握 ggplot2 从数据清洗、异常值发现到分组比较的完整可视化流程并能够按照作业评估标准交出一份兼具清晰注释、完整叙事与美观图表的作品。作业目标从画图到讲故事作业原文见 translations/da/3-Data-Visualization/R/09-visualization-quantities/assignment.md英文原版见 translations/en/3-Data-Visualization/R/09-visualization-quantities/assignment.md给出了明确的任务描述在本课中你使用线图line charts、散点图scatterplots和条形图bar charts来展示这个数据集中的有趣事实。本作业要求你更深入地挖掘数据集去发现关于某一种特定类型鸟类的有趣信息。例如你可以编写一个脚本将你能找到的关于雪雁Snow Geese的所有有趣数据可视化出来。请在 notebook 中使用上述三种图表类型来构建一个故事。该作业的配套讲义 translations/da/3-Data-Visualization/R/09-visualization-quantities/README.mdR 版本原稿见 3-Data-Visualization/R/09-visualization-quantities/README.md提供了完成作业所需的全部技术手段包括用ggplot2绘制线图与散点图观察鸟类最大翼展的分布通过geom_text()标注异常值用subset()过滤疑似录入错误的数据用dplyr的group_by()、summarise()与gather()分组统计并绘制条形图用coord_flip()将条形图转为水平展示通过叠加superimpose多个geom_bar()层进行多指标对比。因此本作业本质上是把讲义中的每一段代码从跟着课文学升级为围绕一个主题自主综合运用。下面我们按作业要求的三种图表讲一个故事的路径完整走一遍。第一步准备数据选定主角作业要求的数据集存放在仓库根目录的 data/ 文件夹下。打开 R 控制台导入数据集并查看前几行birds - read.csv(data/birds.csv, fileEncoding UTF-8-BOM) head(birds)以文件头 5 行为例数据结构是文本与数值的混合体索引NameScientificNameCategoryOrderFamilyGenusConservationStatusMinLengthMaxLengthMinBodyMassMaxBodyMassMinWingspanMaxWingspan0Black-bellied whistling-duckDendrocygna autumnalisDucks/Geese/WaterfowlAnseriformesAnatidaeDendrocygnaLC4756652102076941Fulvous whistling-duckDendrocygna bicolorDucks/Geese/WaterfowlAnseriformesAnatidaeDendrocygnaLC4553712105085932Snow gooseAnser caerulescensDucks/Geese/WaterfowlAnseriformesAnatidaeAnserLC6479205040501351653Rosss gooseAnser rossiiDucks/Geese/WaterfowlAnseriformesAnatidaeAnserLC57.364106615671131164Greater white-fronted gooseAnser albifronsDucks/Geese/WaterfowlAnseriformesAnatidaeAnserLC648119303310130165fileEncoding UTF-8-BOM用于正确处理带 BOM 头的 CSV 文件。作业示例选定的主角是雪雁Snow goose学名Anser caerulescens它在数据集中对应的记录为体长 64–79 厘米、体重 2050–4050 克、翼展 135–165 厘米隶属 Ducks/Geese/Waterfowl 类、Anseriformes 目、Anatidae 科、Anser 属保护状态为 LC无危。选定一个具体物种后作业的关键就成了围绕它的这些数值维度设计出三种图表来回答问题——它体长区间在同类中的位置它的翼展在全数据集中算大还是小它所属类别的数量构成如何第二步线图与散点图——发现异常值完成第一层叙事先装包再画线图用ggplot2的第一步是安装并载入包install.packages(ggplot2) library(ggplot2) ggplot(data birds, aes(x Name, y MaxWingspan, group 1)) geom_line()ggplot()指定数据集与 x、y 轴变量group 1让 ggplot2 把所有离散的 x 值视为一个序列进行连线geom_line()负责绘制线图。此时可以看到一个非常明显的事实至少有一个极端异常值——2000 多厘米的翼展意味着超过 20 米这显然不可能是明尼苏达州真实存在的鸟类多半是录入时多打了一个 0。为了让图表可读作业还要求对坐标轴进行打磨。在 README.md 的构建鸟翼展线图一节中给出了完整的标签优化方案ggplot(data birds, aes(x Name, y MaxWingspan, group 1)) geom_line() theme(axis.text.x element_text(angle 45, hjust 1)) xlab(Birds) ylab(Wingspan (CM)) ggtitle(Max Wingspan in Centimeters)其中theme(axis.text.x element_text(angle 45, hjust 1))将 x 轴标签旋转 45 度xlab()/ylab()分别设置坐标轴标题ggtitle()设置图表标题。生成的效果如讲义中的配图所示用散点图给异常值点名即使旋转 45 度几百个鸟类名称仍无法全部展示。讲义的第二步策略是只标注异常值隐藏其余 x 轴标签改用散点图腾出标注空间ggplot(data birds, aes(x Name, y MaxWingspan, group 1)) geom_point() geom_text(aes(label ifelse(MaxWingspan 500, as.character(Name), )), hjust 0, vjust 0) theme(axis.title.x element_blank(), axis.text.x element_blank(), axis.ticks.x element_blank()) ylab(Wingspan (CM)) ggtitle(Max Wingspan in Centimeters)geom_point()绘制散点geom_text()配合ifelse(MaxWingspan 500, as.character(Name), )只对翼展超过 500 厘米的个体输出鸟名标签hjust 0, vjust 0让标签从点的右上方开始排布三行theme()参数分别隐藏了 x 轴标题、刻度文字与刻度线让画面更清爽。过滤异常值让数据讲道理这一散点图会揭示秃鹰Bald Eagle与草原隼Prairie Falcon的最大翼展各被多加了一个 0。讲义随即用subset()生成剔除异常值的新数据框并重新绘图birds_filtered - subset(birds, MaxWingspan 500) ggplot(data birds_filtered, aes(x Name, y MaxWingspan, group 1)) geom_point() ylab(Wingspan (CM)) xlab(Birds) ggtitle(Max Wingspan in Centimeters) geom_text(aes(label ifelse(MaxWingspan 500, as.character(Name), )), hjust 0, vjust 0) theme(axis.text.x element_blank(), axis.ticks.x element_blank())过滤后数据更加连贯、可解释。需要留意的是过滤后的数据集中最大翼展约为 250 厘米如号手天鹅 Trumpeter swan此时若仍沿用 500的阈值geom_text()将不会再输出任何标签。作为实战改进你可以将阈值下调到过滤后数据的合理区间例如MaxWingspan 240从而继续在高翼展个体上做标注——这也正是围绕具体问题调整可视化参数这一作业能力点的体现。第三步条形图——用分组统计回答数量问题讲义在探索条形图一节提出了一组可以用条形图回答的问题数据集里有多少种鸟类类别各自数量是多少有多少鸟是灭绝、濒危、稀有或常见的在林奈分类体系中各属、各目分别有多少种分组汇总 堆叠条形图先安装并载入数据处理所需的包然后按Category分组对多个数值列求均值并绘制堆叠条形图install.packages(dplyr) install.packages(tidyverse) library(lubridate) library(scales) library(dplyr) library(ggplot2) library(tidyverse) birds_filtered %% group_by(Category) %% summarise(n n(), MinLength mean(MinLength), MaxLength mean(MaxLength), MinBodyMass mean(MinBodyMass), MaxBodyMass mean(MaxBodyMass), MinWingspan mean(MinWingspan), MaxWingspan mean(MaxWingspan)) %% gather(key, value, - c(Category, n)) %% ggplot(aes(x Category, y value, group key, fill key)) geom_bar(stat identity) scale_fill_manual(values c(#D62728, #FF7F0E, #8C564B, #2CA02C, #1F77B4, #9467BD)) xlab(Category) ggtitle(Birds of Minnesota)流程拆解group_by(Category)按类别分组summarise()对六个数值列求均值并记录组内个体数ngather(key, value, - c(Category, n))把宽表转成长表使六个指标可以作为同一个 x 轴类别下的多根柱geom_bar(stat identity)直接使用数值作为柱高scale_fill_manual()为六个指标指定一组明确的色板。coord_flip水平条形图更易读上述堆叠图因未分组数据过多而难以阅读讲义随即给出更实用的方案先统计每个类别下的鸟类数量再用coord_flip()转成水平条形图birds_count - dplyr::count(birds_filtered, Category, sort TRUE) birds_count$Category - factor(birds_count$Category, levels birds_count$Category) ggplot(birds_count, aes(Category, n)) geom_bar(stat identity) coord_flip()dplyr::count(birds_filtered, Category, sort TRUE)统计各类别数量并按降序排列随后把Category列转成与排序一致的因子factor保证 ggplot2 按排序后的顺序绘制coord_flip()将坐标轴对调形成横向条形图。这幅图可以一眼看出该地区数量最多的鸟类类别是 Ducks/Geese/Waterfowl——考虑到明尼苏达州是万湖之地这个结果并不意外。你也可以沿这一思路做其他计数统计例如按ConservationStatus、Order或Genus计数通常会有新的发现。比较与叠加两两对比的进阶叙事讲义比较数据一节展示了基于类别对最大体长进行排序比较的做法birds_grouped - birds_filtered %% group_by(Category) %% summarise( MaxLength max(MaxLength, na.rm TRUE), MinLength max(MinLength, na.rm TRUE) ) %% arrange(Category) ggplot(birds_grouped, aes(Category, MaxLength)) geom_bar(stat identity) coord_flip()结果符合直觉蜂鸟的最大体长最小而鹈鹕与鹅类最大。na.rm TRUE用于在聚合时忽略缺失值。更进一步还可以在同一张图上叠加两个geom_bar()层同时呈现某一类别的最小与最大体长ggplot(data birds_grouped, aes(x Category)) geom_bar(aes(y MaxLength), stat identity, position identity, fill blue) geom_bar(aes(y MinLength), stat identity, position identity, fill orange) coord_flip()position identity让两层柱从同一基线开始绘制、相互覆盖从而直观比较每个类别体长的上界与下界。这种同坐标轴多几何层的手法正是作业中用三种图表讲一个完整故事所需要的进阶技巧。作业示范围绕雪雁构建三段式叙事将以上技术串起来一份达标的作业可以按如下结构组织数据来自 data/birds.csv 中的 Snow goose 记录开场线图/散点图先绘制全数据集的翼展分布指出雪雁在整条曲线中的位置——其翼展区间 135–165 厘米处于中上水平同时借助异常值标注完成对数据集质量的第一印象判断引出为什么要过滤数据这一话题。展开散点图过滤掉秃鹰与草原隼两处录入错误后聚焦鸭雁类Ducks/Geese/Waterfowl对比雪雁与同属的雪雁Rosss goose翼展 113–116 厘米、白额雁Greater white-fronted goose130–165 厘米在体长与体重上的差异。收束条形图用dplyr::count()按Category统计数量说明雪雁所属类别在明尼苏达州是数量最多的类群再叠加MaxLength与MinLength两层条形图展示鸭雁类在体长维度上的跨度。每一步都配上注释例如# 发现雪雁记录中翼展 135–165 cm 处于该类群中位区间并用文字串起因果就同时满足了评分标准中的清晰注释与扎实叙事两项。评估标准自检清单作业的评估标准见 assignment.md分为三档档次要求优秀Exemplary脚本包含清晰注释、有说服力的叙事、吸引人的图表合格Adequate上述三项缺一项需改进Needs Improvement上述三项缺两项对照此表提交前可以逐项自检注释每个代码块是否有#注释说明意图关键步骤装包、分组、过滤、叠加是否解释清楚叙事图表之间是否有逻辑递进发现 → 过滤 → 比较 → 结论能否回答雪雁这个物种在数据集中有什么独特之处美观是否应用了theme()、xlab()/ylab()、ggtitle()、scale_fill_manual()、coord_flip()等让图表更专业的修饰手段仓库中还提供了 Python 版本的第 09 课参考答案 3-Data-Visualization/09-visualization-quantities/solution/notebook.ipynb其中用pandas与matplotlib完成了观察翼展 → 名称与翼展对应 → 标注异常值的同一分析路径可作为对照参考注意该 notebook 为 Python 内核与本文的 R/ggplot2 实现语言不同。延伸挑战讲义末尾的挑战环节建议本数据集提供了特定生态系统内多种鸟类的丰富信息可以继续在网上寻找其他与鸟类相关的数据集围绕新数据练习构图去发现此前未意识到的规律。R 生态中除了ggplot2还可以尝试lattice与plotly等可视化包将同样的数据 → 美学 → 几何思维迁移到更多工具上——这正是本课乃至整个 Data Science for Beginners 课程希望沉淀下来的核心能力。【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进