章节概述

本章作为数据科学实战的逻辑起点,目标是搭建一套可稳定复用的科学计算工作流。你将完成 R 与 RStudio 的环境部署与核心工具集 tidyverse 的配置,并通过引入 R Project 的项目机制与相对路径管理,尽量规避跨平台协作中常见的路径失效与文件组织混乱问题,从而建立更稳健的工程基础。

在此基础上,本章将重点解析 R Markdown 的可复现写作范式。掌握这种“代码与叙述共生”的报告结构,是实现研究过程透明结果可追溯的关键,也将直接支撑你完成本课程后续所有作业与项目报告

本章学习内容

学习导航

本章学习内容

欢迎开始 第 1 章 的学习。请点击 下方导航卡 进入相应小节:

💡 提示:学习完一个小节后,请再次点击 屏幕右下角的章节主页按钮回到本导航页

1.0 RStudio 基础

1.0 RStudio 与 R Project

1.1 初始界面预览

初次安装后启动时,RStudio 主界面默认呈“三栏式”布局(见 Figure 1.1)。为了更好地理解数据分析的工作流,我们需要掌握以下三个核心区域的功能定义:

  • 左侧:控制台 (Console) [Figure 1.1 红框]

    这是 R 语言的执行内核交互中心。在此处输入的指令会被系统立即读取并运行 (Evaluate),随即反馈运算结果。你可以将其视为与 R 引擎进行直接对话的“指令终端”。

  • 右上:环境面板 (Environment) [Figure 1.1 蓝框]

    这是 R 的对象管理器 (Object Manager)。它以清单形式实时展示当前内存中已载入的所有数据对象,包括数据集 (Data Frames)、变量 (Variables) 及自定义函数 (Functions)。它是我们监视数据状态、确保数据成功载入的核心窗口。

  • 右下:多功能面板 (Files/Plots/Packages) [Figure 1.1 绿框]

    这是 R 的资源与输出管理区。该区域集成了文件路径导航 (Files)、可视化图表预览 (Plots) 以及扩展包管理 (Packages) 等多种辅助功能,是连接本地文件系统与分析结果的桥梁。

Figure 1.1 第一次打开RStuido的界面(默认界面)

Figure 1.1 第一次打开RStuido的界面(默认界面)


1.2 第四区域:源代码编辑器

Figure 1.1 的初始界面尚未呈现数据科学工作流中的核心环节——脚本管理控制台 (Console) 虽支持即时交互与反馈,但其操作记录具有易失性。为确保研究过程的持久化存储与研究结果的可复现性,需启用第四大核心区域:源代码编辑器 (Source Editor)


1.2.1 创建 R Script 文档

通过点击 RStudio 界面左上角的 New File 图标,并在下拉菜单中选择 R Script,即可建立新的脚本文件。

新建文档后,界面将转换为标准的四面板工作区 (见 Figure 1.2),新增区域说明如下:

  • 左上:源代码编辑器 (Source) [Figure 1.2 黄框]

    源代码编辑器专用于编写与管理分析代码。与控制台单次输入、即时执行的交互模式不同,在此区域编写的脚本 (Script) 为结构化的指令集合。该模块支持代码的存储、编辑及批量运行,是建立标准化且可复现的数据分析流程的基础。

Figure 1.2 成功创建新文件后的四栏标准工作台

Figure 1.2 成功创建新文件后的四栏标准工作台

类比理解:把 RStudio 当作一间厨房

用一个生活类比快速记住四个面板的分工:

  • Source(编辑器):写“菜谱” (保存流程,便于复现)
  • Console(控制台):下锅执行 (运行/测试代码)
  • Environment(环境):看“食材清单” (当前对象/数据)
  • Plots(绘图区):看“出菜效果” (图表输出)


1.2.2 编写第一段脚本 / R 代码

在新建的默认名为 Untitled1 的空白脚本中输入以下代码。

代码各行末尾均附有注释 (Comments)。添加注释属于规范的编程实践,旨在提升代码的可读性,明确各项指令的具体功能与逻辑意图,从而便于日后的代码审查协同维护

# 1. 字符输出
print("Hello World")  # 将字符串输出至控制台 (Console)

# 2. 基础算术运算
1 + 1                 # 加法运算
4 - 1                 # 减法运算
2 * 2                 # 乘法运算
5 / 2                 # 除法运算

# 3. 对象赋值与操作
x <- 10               # 将数值 10 赋值给对象 x
x^2                   # 计算 x 的平方
y <- 20               # 将数值 20 赋值给对象 y
x / y                 # 计算对象 x 除以 y 的商

# 4. 向量创建与基础函数计算
z <- c(x, y, 30)      # 使用 c() 函数创建包含多个数值的向量 z
mean(z)               # 计算向量 z 的算术平均值

注释符 (#) 与代码文档化

在 R 语言中,井号 (#) 用以标识注释:
# 起至该行末尾的文本均不会被解释器解析或执行。

  • 语法机制
    代码运行时,解释器会自动略过 # 及其后续内容,该部分文本纯粹作为代码解释,不参与任何底层运算。
  • 编程规范
    注释的核心功能在于提升代码的可读性与可维护性。符合学术规范的脚本不仅需确保语法正确,还应具备完善的文档属性。建议利用注释详细记录参数设定的依据与分析步骤的理论支撑 (研究逻辑),而非仅仅复述代码的执行动作。

实践建议: 在代码编写阶段进行详尽的逻辑记录,是保障长期研究项目可复现性的关键环节。对处理步骤与参数依据的严谨注释,可显著降低后期代码审查、重构及协同开发的成本。


1.2.3 运行代码 (Run)

脚本面板内的代码在未经执行前仅作为“纯文本”存在。必须将其提交至控制台 (Console) [.note]进行解析,R 解释器方能执行相应的计算任务。RStudio 提供了两种常规的代码执行途径:


方式一:逐行执行(推荐操作

在标准的数据分析工作流中,通常采用“逐行编写、逐行执行”的模式,以便实时验证输出结果的准确性与逻辑的合理性。

  • 光标定位
    无需高亮选中整行代码,仅需将光标置于目标行的任意位置
  • 执行操作
    • 鼠标点击
      点击脚本面板右上角的 Run 按钮。
    • 快捷键
      • Windows 操作系统: Ctrl + Enter
      • macOS 操作系统: Cmd ⌘ + Enter

运行机制:单行指令执行完毕后,光标将自动下移至次行,从而支持代码的连续执行与测试。


方式二:批量执行

当需要一次性运行多行代码块或完整脚本时:

  1. 选定代码
    使用鼠标拖拽以高亮选中目标代码段。
  2. 执行操作
    点击 Run 按钮,或使用上述相同的快捷键指令。

1.3 项目化工作流:引入 R Project

重要

完成开发环境配置后,需立即构建标准化的项目文件管理体系

数据科学项目通常涉及多种文件类型,如原始数据(.../data/)代码脚本(.../script/)输出图表(.../outputs/)中间结果(.../temp/)等。

Figure 1.3 项目文件分级示意图

Figure 1.3 项目文件分级示意图

若缺乏严谨的目录层级组织,常会导致文件寻址困难、版本控制混乱,以及因文件路径 (File path) 配置错误而引发的代码执行中断。为此,RStudio 引入了基于 R Project (R 项目) 的标准化项目管理工作流。


1.3.1 核心机制:工作目录的锚定

R Project 的核心机制在于为特定的分析任务构建一个自包含的工作环境 (Self-contained)

创建 Project 后,RStudio 将自动把项目根目录设定为当前工作目录 (Current working directory)。该目录即作为文件寻址的锚点:后续所有文件的读取与存储操作均以此作为基准起点,进而确立稳定且具备高度复用性的项目架构。

  • 传统模式的局限
    高度依赖绝对路径 (Absolute path)(如 C:/Users/Name/Documents/Analysis/data.csv)。当项目文件发生物理迁移、目录结构重组或跨设备操作时,极易导致路径失效与代码运行中断。
  • R Project 的优势
    支持采用相对路径 (Relative path)(如 data/survey.csv)。在项目文件夹内部结构保持不变的前提下,即使项目整体发生迁移,代码路径依然有效。此机制大幅提升了数据分析的可移植性可复现性

不要在代码中使用绝对路径

初学者最常见的错误之一,是在代码里写 绝对路径 (Absolute path)。例如读取 survey.csv

❌ 错误示例(绝对路径)

my_data <- read.csv("C:/Users/张三/Desktop/survey.csv")

(含义:让 R 去某台电脑的 C 盘、某个用户目录下逐层查找文件)


为什么不推荐?
这种写法强依赖本机目录结构 (Local dependency):同一段代码往往只能在当前电脑上运行。一旦更换电脑/账号,或把代码发给同学、助教与导师,路径就可能不存在,进而导致读取失败并报错


✅ 推荐做法(相对路径)
R Project 下,使用相对路径 (Relative path):只需写明文件在项目中的相对位置即可,例如 data/survey.csv

my_data <- read.csv("data/survey.csv")

(含义:从当前项目根目录出发,到 data/ 文件夹中读取数据)
一句话总结:只要文件仍在项目文件夹内,无论项目被移动到哪里,相对路径通常都能保持有效 (Portability & Reproducibility)


1.3.2 创建新的 R Project

本节将详细阐述遵循标准规范的 R Project 创建流程。

Step 1 启动向导:点击 RStudio 界面右上角的 立方体图标 (Project),并在下拉菜单中选择 New Project…


Step 2 选择类型:在弹出的向导窗口 (Wizard) 中 (见 Figure 1.4 - 1.5),依次进行以下操作:

Figure 1.4 创建新R Project步骤:1

Figure 1.4 创建新R Project步骤:1

Figure 1.5 创建新R Project步骤:2

Figure 1.5 创建新R Project步骤:2

Step 3 设置详情:此步骤用于确定项目的物理存储路径,需遵循系统命名规范。

  • Directory name (目录名)
    输入 Chapter_1
  • Create project as subdirectory of
    点击右侧 Browse 选择用于存放该项目的主文件夹路径。
  • 完成上述设置后,点击 Create Project。RStudio 将自动重载工作环境,界面右上角将显示当前项目名称 Chapter_1
Figure 1.6. 创建新R Project步骤:3

Figure 1.6. 创建新R Project步骤:3

⚠️ 核心命名规范

为确保代码运行的长期稳定性与跨平台兼容性,文件及文件夹的命名需严格遵循以下三项核心原则:

  • 避免使用中文字符
    R 语言环境对非 ASCII 字符(如中文)路径的支持存在局限,极易在文件读取与写入过程中引发编码错误或乱码问题。
  • 禁止使用空格
    文件系统中包含空格的路径易导致解释器解析异常。建议使用下划线 (_) 或连字符 (-) 作为替代词缀分隔符(例如 final_project)。
  • 规避特殊符号
    严禁使用系统保留字符或特殊符号(如 /, :, *, ?, <, >, | 等),以防干扰底层系统的路径解析机制。

1.3.3 核心原则:项目文件的标准启动流程

重要

项目创建完成后,指定的系统目录下将自动生成以 .Rproj 为扩展名的配置文件。为确保工作环境的正确加载与相对路径的生效,需遵循以下标准化启动流程

💡 项目环境的正确加载机制

每次开启分析任务时,请务必通过以下两种规范途径之一激活项目环境:

  • 途径一:基于文件系统的直接启动 在操作系统的文件资源管理器中,直接双击运行 .Rproj 配置文件。

    ⚠️ 避免错误操作:切勿直接双击打开 .R (R Script).Rmd (R Markdown) 等具体的脚本文件。此操作仅会加载单一文本文件,无法激活关联的 R Project 环境,进而导致工作目录未被正确锚定以及后续的文件读取报错。

  • 途径二:基于 RStudio 界面内的项目切换 若已预先启动 RStudio 主程序,可通过点击界面右上角的项目管理下拉菜单 (Project Menu),选择 Open Project… 或从最近项目列表中点击目标名称,以切换至对应的 .Rproj 工作环境。


2.0 R 包的管理

2.0 R 包的管理

载入新建的 Chapter1 项目环境后,RStudio 界面通常默认呈现三面板布局。其原因在于:当前工作区尚未载入或创建任何脚本文件,致使源代码编辑器 (Source 面板) 处于未激活状态。

在系统性论述 R 包机制前,需预先在当前项目中创建并存储代码脚本文件,以此作为后续指令执行与逻辑记录的基础载体。


2.1 脚本文件的构建与存储

基于 1.2 节详述的操作规范,在当前项目中构建新脚本文件的标准流程如下:

Step 1 初始化脚本
点击 RStudio 工具栏左上角的 图标,并在下拉菜单中选择 R Script。执行此操作后,界面左上方的源代码编辑器将被激活并展开为标准的四面板布局

Step 2 持久化存储
新建脚本后,需立即执行保存操作以防数据丢失。点击源代码编辑器上方的 (Save) 图标,将该文件命名为 lab_01.R。系统将默认把该脚本写入并留存于当前 R Project 的工作目录之中。


2.2 核心概念:Base R 与扩展包

重要

R 包 (Package) 本质上为特定功能模块的标准化集合,通常封装了自定义函数、帮助文档及示例数据集。R 语言在数据处理、统计建模与可视化等领域的核心优势,高度依赖于此类包的协同运作。

为深入解析 R 语言的运行机制,需界定以下两个架构层级:

  • 基础 R (Base R):即 R 的原生系统层。在初始安装阶段即默认配置的一系列核心包 (Base and recommended packages),提供最底层的通用计算与基础统计能力。
  • 扩展包 (Extension packages):由全球开发者社区维护并托管于 CRAN 等中央存储库的外部功能模块,用于针对性地拓展专业分析能力。

在概念模型上,此架构类似于“智能手机生态” (见图 2.1)

Figure 2.1. R 与 R Packages/Libraries 的关系比喻

Figure 2.1. R 与 R Packages/Libraries 的关系比喻

基础 R (Base R) 相当于操作系统的预装核心组件 (Out-of-the-box)。它具备基础运算能力,但在应对高度复杂或专业化的分析任务时存在局限性。

R 包 (Packages) 则相当于按需安装第三方应用程序 (Applications)。例如,通过引入 ggplot2 包可构建现代化的数据可视化工作流,引入 dplyr 包则能显著提升数据清洗与操作的执行效率。借助此类模块化扩展机制,R 语言的分析能力得以根据具体的研究需求进行无缝拓展。


这些“APP”从何而来?

  • CRAN (可理解为“官方仓库”)
    全称 The Comprehensive R Archive Network。多数常用包发布在 CRAN,上架需要符合 CRAN 的提交规范,并通过一系列自动化检查与跨平台构建测试 (Quality checks)
    通常使用 install.packages() 安装,版本相对稳定,适合课程与常规科研复现。

  • GitHub(及其他开发者平台)
    一些包会先以“开发版/研究前沿工具”的形式托管在 GitHub,未必同步发布到 CRAN。此时可用 devtools (或更轻量的 remotes 直接从仓库安装:

    install.packages("devtools")  # 仅需安装一次
    devtools::install_github("houseofcommonslibrary/statxplorer")

    示例用途:下载公开数据 statxplorer 是一个用于访问英国 DWP Stat-Xplore Open Data API 的 R 包,可把 API 查询结果返回为便于分析的数据结构(需先注册并获取 API key)(API key)


2.3 运行机制:安装与加载

重要

明确了 R 包 (Package) 在 R 生态系统中的定位后,掌握其管理机制是后续分析的基础。该管理流程的核心操作主要分为两个步骤:安装 (Install)加载 (Load)

这两个操作在执行频率与代码语法上存在显著差异。为直观区分,可参考“灯泡与开关”的概念模型 (见 Figure 2.2)

  • 安装包 install.packages("包名"):相当于“安装灯泡”
    • 操作逻辑:将目标包从中央存储库下载并部署至本地计算机的 包库 (Library) 中。
    • 执行频率:单次配置;通常只需操作一次,除非面临设备更换、软件重装或环境重置等情况。
    • 版本维护:若需获取已安装包的最新版本,可执行 update.packages() 函数。
  • 加载包 library(包名):相当于“打开开关”
    • 操作逻辑:在当前的 工作会话 (Session) 中激活该包,使其内置函数处于可用状态。
    • 执行频率:高频操作;通常每次启动新的工作环境时均需重新执行。处于安装状态但未被加载的包,其内部函数无法被直接调用。
Figure 2.2. R 与 R 安装和加载包 的关系比喻

Figure 2.2. R 与 R 安装和加载包 的关系比喻


2.3.1 语法差异:引号的使用规则

重要

在代码编写过程中,安装 (Install)加载 (Load) 存在一个易被混淆的语法特征:引号的有无

参数传递机制:引号的作用

对比以下两条常用指令:

  • 安装阶段:需使用引号 install.packages("tidyverse")
    (安装时需将包名作为字符串传递给存储库进行检索与下载,因此需加引号)

  • 加载阶段:通常省略引号 library(tidyverse)
    (加载时直接按名称调用当前工作环境中已安装的模块,通常无需将其作为字符串处理)

(补充说明:library("tidyverse") 的写法同样有效,但在实际编码中更倾向于采用省略引号的常规形式)


2.3.2 基于图形界面的包管理机制

可选操作 (菜单栏工具安装)

除命令行操作外,RStudio 提供了基于 图形用户界面 (Graphical user interface, GUI) 的程序包管理方案,便于直观地执行相关维护操作。

在右下角工作区选择 Packages 标签,界面将呈现以下核心功能:

  • 已安装模块列表:展示包名、版本信息及当前的加载状态 (以复选框勾选状态表示)
  • 安装:用于检索并部署新包。
  • 更新:用于升级已安装包的版本。

提示:基于图形界面的包管理操作,其底层机制仍是在控制台调用相应的 R 语言指令,仅在交互层面进行了可视化封装。


2.4 核心扩展包的配置与加载

基于前述的包管理机制,本节将在新建的 lab_01.R 脚本中进行基础数据科学工具包 tidyverse 的配置与加载。

2.4.1 核心工具集简介:tidyverse 元程序包

在 R 语言生态系统中,tidyverse 通常被定义为元程序包 (Meta-package)。它并非提供单一功能的独立模块,而是整合了一系列设计哲学一致、底层数据结构兼容且能高效协同工作的包集合。

在概念上,其功能定位类似于数据科学领域的“多功能集成工具” (强调高度集成与通用性)tidyverse 依托于整洁数据 (Tidy data) 的核心理论,功能覆盖数据导入、清洗、结构转换与可视化等标准分析流程,为常规数据科学任务提供了一套高度标准化的工具链。

此类集成化架构的主要优势体现在以下两个维度:

  1. 部署效率
    免去了逐一配置离散功能的繁琐步骤;对于常规的基础分析工作流,通常仅需部署 tidyverse 即可基本满足需求。
  2. 语法一致性
    各子包间的函数命名规范与数据操作逻辑高度统一,支持在“数据清洗—结构转换—统计绘图”等不同环节间实现顺畅的数据流转,从而有效降低长期学习与跨团队协作的成本。
Figure 2.3. R 与 R Packages: tidyverse

Figure 2.3. R 与 R Packages: tidyverse

知识拓展:Tidyverse 生态宇宙

tidyverse 是一套基于共享设计哲学、语法规范及通用数据结构构建的 R 包集合。其并非单一功能的扩展模块,而是系统性整合了现代数据科学工作流的分析生态。安装部署完成后,系统将默认包含以下核心组件 (点击卡片可访问官方文档)

ggplot2 可视化

dplyr 数据操控

tidyr 数据规整

readr 数据读取

stringr 文本处理

未列出的包:如lubridate (时间日期 ), tibble (现代数据框), purrr (函数式编程) 等。

Tidyverse 官网


2.4.2 代码编写与执行

请回到左上角的 Source,在 lab_01.R 文件中输入以下代码:

# --- Step 1: 安装 (只需运行一次) ---
# 注意:包名必须加引号
install.packages("tidyverse")

# --- Step 2: 加载 (每次重启 RStudio 后需重新运行) ---
# 注意:包名无需引号
library(tidyverse)

操作回顾:逐行执行 (Run)

基于 1.2.3 节 的操作规范,将光标定位至代码首行,并通过以下快捷键发送执行指令:

  • Windows: Ctrl + Enter
  • macOS: Cmd ⌘ + Enter


运行机制:单行指令执行完毕后,光标将自动下移至次行,以支持代码的连续解析与运行。

若指令解析正常 (成功下载、配置并调用 library(tidyverse)),控制台 (Console) 将反馈如下环境加载信息。该加载详情通常仅在当前工作会话初次调用该模块时输出;后续重复加载时默认不再显示

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.6
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.2     ✔ tibble    3.3.1
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.2.0     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter()     masks stats::filter()
✖ dplyr::group_rows() masks kableExtra::group_rows()
✖ dplyr::lag()        masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors


tidyverse 加载日志解析与逻辑说明

执行 library(tidyverse) 指令后,控制台 (Console) 会反馈详细的加载日志。该信息核心反馈了以下三个维度的环境状态:激活的模块构成、各组件版本信息、以及函数命名冲突提示


1) 环境挂载信息 Attaching core tidyverse packages ...
  • 挂载 (Attaching):指将 tidyverse 的核心功能模块导入当前 工作会话 (Session)。挂载完成后,相应模块内置的函数即可在当前环境中直接调用。
  • 版本标识:例如 tidyverse 2.0.0 代表该元程序包的整体版本。需明确的是,tidyverse 作为 包集合 (Meta-package),其内部各子组件均拥有独立的版本演进。

2) 核心组件清单与功能概览

日志列出了随 tidyverse 自动加载的一组 核心扩展包 (Core packages),格式通常为 ✔ 包名 版本号

常用组件及其主要分析功能概览如下:

  • dplyr:数据操纵与逻辑变换 (如筛选、汇总、连接等)
  • ggplot2:基于图形语法的数据可视化
  • readr:结构化文本数据 (如 CSV, TSV) 的读取
  • tidyr:数据重塑与规整 (如长宽表转换)
  • tibble:现代化、易读性更高的轻量级数据框
  • stringr:字符串处理与正则表达式工具
  • forcats:因子型 (Factor) 变量的处理
  • lubridate:日期与时间数据的解析
  • purrr:泛函编程与迭代工具

逻辑说明:在初阶分析阶段,无需记忆各包的全量函数。重点在于理解 tidyverse 构建了一套高度协同的分析工具链,能够覆盖数据处理的全生命周期。


3) 函数命名冲突提示 Conflicts ...

该部分旨在提示:不同程序包中存在同名函数,R 需根据优先级确定默认执行的函数。

例如当控制台显示:dplyr::filter() masks stats::filter()

  • 遮蔽 (Masks):表示直接调用 filter() 时,R 将优先执行 dplyr 的版本,而 stats 包中的同名函数在默认情况下被覆盖。
  • 命名空间运算符 (Namespace operator):即 :: 符号,用于显式指定特定包内的函数。
    • dplyr::filter():明确调用 dplyr 包中的函数。
    • stats::filter():明确调用 stats 包中的函数。

处理函数冲突的规范做法:

  • 显式声明命名空间(推荐):使用 包名::函数名() 形式书写代码,可有效消除歧义,提升代码在跨环境操作时的稳定性与可复现性。
  • 查询实时冲突:通过调用 tidyverse_conflicts() 函数,可实时获取当前环境下的命名冲突清单。

4) 进阶管理建议 (可选了解)

若需在开发流程中强制规避潜在的同名函数调用风险,可引入 conflicted 包。该模块会将冲突情况转化为报错提示,要求开发者显式选择所需的函数版本。在入门阶段,仅需知晓其功能定位即可。

3.0 文档架构

3.0 R Markdown

“R Markdown provides a unified authoring framework for data science, combining your code, its results, and your prose commentary.” > — Hadley Wickham & Garrett Grolemund

在传统的数据分析流程中,“数据解析” (运行代码)“成果产出” (撰写报告) 通常处于解构状态。

这种分离模式会导致“结果静态化”的局限:一旦原始数据或分析逻辑发生变更,研究者必须重复执行 “重运行脚本 → 导出图表 → 人工更新报告” 的繁琐流程。此类操作不仅增加了维护成本,且在版本控制与图表替换过程中极易引入人为错误 (如数据不一致或内容遗漏)

R Markdown (.Rmd) 引入了高度集成的写作范式:它将 代码 (Code)运算结果 (Results)叙述性文本 (Narrative) 封装于同一份可执行文档内,从而将分析过程与报告呈现整合为统一的可复现工作流 (Reproducible workflow)

当需更新分析内容时,仅需执行一次 Knit 操作 (编译/渲染):系统将按逻辑顺序自动重新解析代码块,并实时生成最新的统计表、可视化图表及结论说明,确保分析结果与报告内容的同步更新。

Figure 3.1. 传统工作流 (左) 与 R Markdown 工作流 (右) 的对比

Figure 3.1. 传统工作流 (左) 与 R Markdown 工作流 (右) 的对比


3.0.1 R Markdown 的主要应用场景

R Markdown 能够有效覆盖数据分析中三类核心的沟通与记录场景:

1. 决策支持维度
决策层通常更关注结论与建议而非底层技术细节。R Markdown 支持在输出文档中隐藏代码块,仅呈现关键图表与统计分析结果,从而生成聚焦于业务洞察的专业报告。

2. 团队协作维度
协作流程通常涉及对分析逻辑与结果来源的复核。R Markdown 将计算代码、运算输出与逻辑解释整合于同一文档,提升了分析过程的透明度,并增强了研究的可复现性 (Reproducibility)

3. 知识管理与长期维护
数据分析包含大量中间决策与假设验证过程。R Markdown 作为动态研究日志,可完整记录分析思路、参数选择与关键逻辑解释,有效降低了后续回溯与维护的认知成本。


3.0.2 技术原理与渲染工作流

掌握 R Markdown 的基本运行机制有助于构建稳定的分析流。该系统主要由以下两个层级构成:

1. 核心基础:Markdown (Plain text)
R Markdown 的写作基础为 Markdown,这是一种强调易读性与轻量化的标记语言。

  • 纯文本属性:不依赖特定的闭源排版系统,兼容各类文本编辑器,且便于执行版本管理。
  • 结构化语法:利用简洁符号定义文档结构与样式 (如使用 # 标识标题,使用 ** 标识加粗),使撰写过程聚焦于内容逻辑而非排版细节。

2. 功能扩展:R Markdown (Integrated code blocks)
在 Markdown 基础上,RStudio 引入了 knitr (Rendering engine)。该架构的核心能力在于:在正文中嵌入可执行的代码块,并将运算产出的表格、图形或数值自动整合至最终文档。

执行 “Knit” (渲染) 操作时,系统将启动自动化处理流 (Pipeline)

  1. knitr:解析并执行代码块,生成运算结果与相应的可视化图表。
  2. Pandoc:对文本与计算输出进行格式转换与排版处理。
  3. Output:生成最终格式的目标文档 (如 HTML、Word 或 PDF)

3.1 环境准备与新建

3.1.1 扩展模块配置

RStudio 通常预装了基础支持。为确保环境功能的完整性,需在初始阶段执行以下指令以配置核心编译组件:

# 安装 R Markdown 核心功能包
install.packages("rmarkdown")

# 安装渲染引擎包
install.packages("knitr")

3.1.2 构建 R Markdown 文档

R Markdown 文档的创建过程遵循标准化的交互流程,主要涵盖文件初始化与基础元数据 (Metadata) 配置两个阶段。


Step 1 文件创建

点击 RStudio 顶部工具栏左上角的 图标,并从下拉菜单中选择 R Markdown… 选项。


Step 2 初始设置

在弹出的配置窗口中,需定义文档的核心元数据 (见 Figure 3.2)

  • Title:文档标题。
  • Author:署名作者。
  • Default Output Format:初始阶段建议设定为 HTML 格式。

确认配置后 (点击 OK),系统将自动生成包含预设示例内容的 .Rmd 模板文件,支持在此基础上直接执行内容编辑与功能扩展。

Figure 3.2 创建新 R Markdown

Figure 3.2 创建新 R Markdown


3.1.3 默认文档结构解析

成功初始化文档后,编辑器将自动加载一段模板文本 (Template)。该模板的逻辑架构可解构为以下四个核心组成部分:

1. 元数据区域 (YAML Header)

  • 位置:起始于文档顶端,由两组连续的短横线 --- 封装。
  • 功能定义:该区域作为文档的全局元数据 (Metadata) 配置区,用于规范文档的标题、作者信息以及预设的输出格式。示例配置如下:
---
title: "First Practice"     # 文档的主标题 (默认是一级标题)
author: "YunzheLiu"         # 作者署名
date: '`r Sys.Date()`'      # 日期 (此处使用的 R 代码运行后自动获取当前日期)
output: html_document       # 输出格式 (HTML网页)
---

核心概念:YAML 配置语言

YAML (YAML Ain’t Markup Language) 是一种轻量化的配置管理语言。在 R Markdown 文档中,该区域负责元数据 (Metadata) 的定义,涵盖标题、作者、日期及输出格式等核心参数。后续亦可用于扩展目录 (Table of Contents)、视觉主题及代码高亮样式等进阶设定。

配置过程中建议遵循以下排版规范:

  1. 冒号后的空格要求:在键名与键值之间需插入一个空格。
    • 规范形式:title: My Report
    • 非规范形式:title:My Report
  2. 缩进方式的选择:YAML 语法对层级逻辑具有高度敏感性。建议仅使用空格 (通常为 2 个字符) 进行对齐,避免使用 Tab 键,以防导致渲染解析异常或配置失效。


2. 全局设置区 (Global Setup Chunk)

  • 位置:通常位于 YAML 区域下方的首个代码块。该区域由三反引号封装,并在花括号内声明编程语言及配置参数。
  • 功能定义:该区域作为文档的全局默认配置项,用于统一调控后续各代码块的执行行为与显示模式。例如,可通过设定 knitr::opts_chunk$set(echo = TRUE) 来规范全文代码块的可见性。
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
  • setup (代码块标签):该代码块的唯一标识名称。在复杂的文档中,为代码块分配唯一的标识通常有助于后期的维护与错误定位。
  • include = FALSE (参数设定):使代码块在渲染过程中处于“静默执行”状态。这意味着代码将被运行,但其源码及其产出的任何结果都不会在最终报告中显示。
  • echo = TRUE (参数设定):设定后续所有代码块的默认显示逻辑。在此参数下,报告通常会同步展示代码源码与其执行结果,以增强分析过程的透明度。


3. 文本写作区 (Markdown Text)

  • 位置:文档中未被代码块 (Chunk) 包裹的任意区域。
  • 功能定义:这是文档的主体部分,支持使用标准的 Markdown 语法撰写研究背景、方法论解析以及最终的数据结论。
## R Markdown
This is an R Markdown document. Markdown is ... 

以及

## Including Plots
You can also embed plots, for example:

以及

Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.
  • ##:二级标题 (Heading level 2)
    例:## 研究背景

  • 正文:直接输入即可 (与 Word 类似)

  • 超链接有两种常用写法:

    1. 自动链接(只显示网址)
      模板:<网址>
      例:<http://www.baidu.com>

    2. 命名链接(显示文字,更推荐)
      模板:[显示文字](网址)
      例:[百度](http://www.baidu.com)

  • 行内代码 (Inline code):用一对反引号包起来
    模板:`代码`
    例:这样写:`code`

4. 示例文本中的 代码运行区 (R Code Chunks)

  • 位置:由三个反引号 ```{r} 开头,并由三个反引号 ``` 结尾的区域。
  • 定义:这是用于编写并执行 R 代码的独立区域。在此区域内的文本会被 RStudio 识别为代码命令而非普通文字。
```{r cars}
summary(cars)
```

以及

```{r pressure, echo=FALSE}
plot(pressure)
```


  • {r cars}
    • r:声明该代码块使用 R 语言 (engine)
    • cars:该代码块的标签 (label),用于标识与定位这个代码块(便于排错与引用)。
    • summary(...):用于输出数据的描述性统计 (descriptive statistics),例如最小值、四分位数、中位数、均值、最大值等。
    • cars:R 自带的示例数据集 (内置数据集),包含车辆速度与刹车距离的观测值。


  • {r pressure, echo=FALSE}
    • pressure:该代码块的标签 (label)
    • echo=FALSE:表示不显示代码,只显示输出 (结果/图形)
    • plot(...):基础绘图函数,用于生成图形输出 (plot)
    • pressure:R 自带的示例数据集 (内置数据集),记录温度与汞蒸气压之间的关系。


运行机制:一键渲染 (Knit)

点击编辑器上方的 Knit (编织/渲染) 按钮后,系统将按文档的逻辑顺序依次解析并执行各代码块 (Code Chunks)

在此过程中,后台会同步处理文档内的计算逻辑与绘图指令。例如,执行 summary(cars) 以获取描述性统计结果,或通过 plot(pressure) 生成可视化图表。运算产出的数值、表格及图形将依据预设的逻辑结构,自动整合至最终生成的输出文档中,从而确保分析记录与展示结果的高度同步。

4.0 R Markdown 语法

4.0 Markdown 语法速查

Markdown 的核心设计哲学在于内容驱动的文档构建:其通过标准化的标记符号实现文档的结构化排版,从而有效降低了复杂的排版样式调整对撰写过程的干扰。

以下为常用的基础语法概览。


4.1 标题与层级 (Headers)

在 Markdown 语法体系中,通常采用井号 # 作为标题 (Headers) 的标识。井号的数量对应文档的逻辑层级,且各层级的视觉权重通常随深度增加而依次递减。

你的输入 预览效果
# 一级标题 一级标题
## 二级标题 二级标题
### 三级标题 三级标题
...

关键规则:空格不能少!

井号 # 与标题文字之间必须保留一个空格

  • 正确## 标题 (会被识别为标题)
  • 错误##标题 (通常会被当作普通文本)

补充:Markdown 标题最多支持 6 级(######)。


4.2 文本样式与格式化 (Text Formatting)

在 Markdown 语法中,文本样式的实现主要依赖于特定标识符对目标字符的“封装”。以下为数据分析报告中常用的格式化指令:

语法 你的输入 预览效果
加粗 **重点内容** 重点内容
斜体 *辅助说明* 辅助说明
删除线 ~~过时信息~~ 过时信息
行内代码 `mean()` mean()
上标/下标 X^2^ / H~2~O X2 / H2O
换行(软换行) 行末两空格 + 回车 (同段内换行)
分隔线 --- (水平分隔线)

文本格式化应用逻辑与规范

  • 加粗 (Bold):用于强调核心结论或关键性规则。建议仅针对局部关键术语进行标注,避免全文大范围应用以保持视觉重点的有效性。
  • 斜体 (Italics):通常用于标注补充性说明、专业术语或轻量级的语义强调。
  • 删除线 (Strikethrough):用于保留历史分析记录或已弃用的结论,以此向读者明确该内容已不在当前版本中采纳 (在学术性报告中应用频率相对较低)
  • 行内代码 (Inline Code):适用于标注函数名称、参数配置、数据对象或变量。例如 filter()echo = TRUEmy_data
  • 上标与下标 (Superscript and Subscript):主要应用于数学表达式、度量单位或化学式。例如 km^2^H~2~O

常见误区:行内代码 ≠ 高亮强调

行内代码 `...` 的主要作用是“把它当作代码/符号”来呈现 (monospace),适合函数与参数。
如果你只是想强调一句话,更推荐用 加粗斜体


4.3 列表

列表常见两类:无序列表 (圆点)有序列表 (编号)
写作建议:无序列表适合“并列要点”,有序列表适合“步骤流程”。


A. 无序列表

无序列表可用 -*+ 开头(建议全篇统一使用一种符号,最常用的是 -)。

语法 你的输入 预览效果
基础列表 - 苹果
- 香蕉
• 苹果
• 香蕉
层级嵌套
(子列表)
- 水果
    - 苹果
    - 香蕉
• 水果
    ◦ 苹果
    ◦ 香蕉
同一条内换行
(同一个 bullet)
- 研究对象:伦敦 OAs
  (数据来源:2021 Census)
• 研究对象:伦敦 OAs
    (数据来源:2021 Census)

关键规则:空格与缩进

  1. 符号后必须有空格- 后要加空格 (写成 -Item 通常不会被识别为列表)
  2. 缩进产生层级:子列表建议使用 4 个空格 (或 Tab),并保持对齐一致

B. 有序列表

有序列表使用 1.2. 这类“数字 + 点”开头。

语法 你的输入 预览效果
基础排序 1. 打开 RStudio
2. 新建文件
3. 保存
1. 打开 RStudio
2. 新建文件
3. 保存
懒人编号
(自动纠正)
1. 第一步
1. 第二步
1. 第三步
1. 第一步
2. 第二步
3. 第三步
步骤中含子要点 1. 读取数据
    - 检查缺失值
    - 统一变量类型
1. 读取数据
    • 检查缺失值
    • 统一变量类型

应用建议:叙述性链接的优势

相较于直接展示长 URL,采用 [描述文本](URL 路径) 的形式通常更具可读性:读者可直观理解链接指向的内容,且文档布局更为整洁。

图像引用亦遵循类似逻辑:建议在 ![替代文本](...) 字段中清晰阐述图像的核心内涵。这不仅有助于图像检索,也为辅助技术 (如屏幕阅读器) 提供了必要的上下文信息,确保了文档的无障碍访问 (Accessibility)

典型异常识别

  1. 引导符遗漏:若忽略首位的感叹号 !,Markdown 渲染引擎将按照普通文本链接进行解析,导致图像无法在最终文档中可视化。
  2. 路径引用策略:在圆括号 (...) 中定义的资源路径通常分为以下两类:
    • 网络链接:以 httphttps 协议开头。
    • 本地资源:建议采用相对路径 (Relative path),例如 images/my_plot.png

运行逻辑:使用相对路径有助于提升项目的可迁移性。当整个项目文件夹移动至其他设备或目录时,只要资源与脚本的相对位置保持不变,文档通常仍可正常渲染。

进阶技巧:基于代码块的图像控制

重要

Markdown 原生的图像语法在属性控制 (如精确尺寸调整、对齐方式、自动编号与题注) 方面存在一定局限性。若需实现更精细的排版控制,推荐通过 R 代码块 调用 knitr::include_graphics() 函数:

```{r, echo=FALSE, out.width="50%",fig.align='center', fig.cap="Figure X.图片标题"}
knitr::include_graphics("/我的图片/图片x.png")
```

常用参数说明

  • echo=FALSE:不显示代码,只显示图片输出 (适合正式报告)
  • knitr::include_graphics():插入图片文件 (支持 png/jpg/pdf 等)
  • out.width="50%":输出宽度为页面宽度的 50% (也可写 "300px"
  • out.height="200px":设置输出高度 (可与 out.width 配合使用)
  • fig.align='center':图像对齐方式 (‘left’ / ‘center’ / ‘right’)
  • fig.cap="...":图题 (caption),用于解释图像含义并支持自动编号(取决于输出格式设置)
  • fig.alt="...":替代文本 (无障碍阅读与检索更友好)

4.5 引用与分割线

  • 引用:用于摘录一段话、强调重点或表示“注脚”。
  • 分割线:用于在视觉上把文档切分成上下两部分。
语法 你的输入 预览效果
区块引用
(大于号)
> 这是一个重要的定义
> 也是重点
这是一个重要的定义
也是重点
分割线
(三个短横线)
--- ────────────────────

举个例子:

我们输入这个:

> "I thoroughly disapprove of duels. If a man should challenge me,
  I would take him kindly and forgivingly by the hand and lead him
  to a quiet place and kill him."
>
> --- Mark Twain

Knit之后的效果:

“I thoroughly disapprove of duels. If a man should challenge me, I would take him kindly and forgivingly by the hand and lead him to a quiet place and kill him.”

— Mark Twain

使用小技巧

  1. 引用嵌套:你甚至可以使用 >> 来创造“引用中的引用”(双层缩进)。
  2. 分割线避坑:输入 --- 时,上下最好各空一行。如果 --- 紧贴在文字下方,Markdown 可能会把它误认为是“二级标题”的标记。

4.6 数学公式 (LaTeX Math)

R Markdown 完美支持 LaTeX 数学公式。公式主要分为 行内 (Inline) 和 独立 (Display) 两种。

语法 你的输入 预览效果
行内公式
(一个 $ 符号)
$E=mc^2$ 是质能方程 \(E=mc^2\) 是质能方程
上标与下标
(常用的 ^_)
X^2^ (上标)
H~2~O (下标)
$X_i$ (数学下标)
X2
H2O
\(X_i\)
希腊字母
(斜杠+读音)
$\alpha$
$\beta$
$\pi$
\(\alpha\)
\(\beta\)
\(\pi\)

进阶:如何写复杂的大公式?

如果你想写那种独占一行、居中显示的大公式,请使用 两个 Dollar 符 $$ 包裹:

$$
\sum_{i=1}^{n} (x_i - \bar{x})^2 
\qquad \text{与} \qquad 
X = \begin{bmatrix}
1 & x_{1}\\
1 & x_{2}\\
1 & x_{3}
\end{bmatrix}
$$

Knit之后的效果:

\[ \sum_{i=1}^{n} (x_i - \bar{x})^2 \qquad \text{与} \qquad X = \begin{bmatrix} 1 & x_{1}\\ 1 & x_{2}\\ 1 & x_{3} \end{bmatrix} \]


4.7 代码:行内代码与代码块

R Markdown 的核心优势之一,是可以在同一份文档中同时写 叙述文本可执行代码。这里有两个最重要、也最容易混淆的概念:行内代码(Inline Code)代码块 (Code Chunks)


4.7.1 行内代码:把结果“嵌入一句话里”

行内代码用于把一个计算结果插入到文本中,语法是:

  • 用一对反引号包裹,并在开头写 r
`r​ 表达式` 
用途 你的输入 预览效果
自动插入日期 今天日期:`r​ Sys.Date()` 今天日期:2026-03-19
插入计算结果 2 + 3 = `r​ 2 + 3` 2 + 3 = 5
插入对象值 样本量 n = `r​ nrow(mtcars)` 样本量 n = 32

关键规则:行内代码适合“短小表达式”

  • ✅ 适合:日期、简单运算、一个对象的值(如 nrow()mean()
  • ❌ 不适合:多行代码、复杂数据处理、绘图等(这些请用“代码块”)

4.7.2 代码块:运行一段完整 R 代码

重要

代码块用于执行一段相对完整的代码(多行也可以),并把输出(表格/文字/图)呈现在报告中。基本结构如下:

```{r}
x <- 1:5 # 将一个数值向量(从 1 到 5 的整数序列)赋值 (‘<-’) 给变量 x
mean(x)  # 计算 x 向量中所有数值的平均值: (1 + 2 + 3 + 4 + 5) / 5
```

在代码块中,你可以执行任何有效的 R 代码,R Markdown 会自动捕获并显示代码的输出。以下是一些常用的参数设置,可以帮助你自定义代码块的行为:

  • eval

eval 参数决定是否执行代码, 默认值是 TRUE,表示代码会被执行。如果将其设置为 FALSE代码会被展示,但不会运行。常用于需要展示代码而不执行的情况。

```{r, eval=FALSE}
x <- 1:5
mean(x)
```
  • echo

echo 参数决定是否在输出中显示代码。默认值是 TRUE,即显示代码。如果将其设置为 FALSE代码不会显示,只会显示结果

```{r, echo=FALSE}
x <- 1:5
mean(x)
```
  • results

results 参数控制如何显示代码输出。常见的设置有:

  1. markup:默认值,输出为格式化文本

  2. asis:原样显示输出,不进行格式化

```{r,results='asis'}
cat("比较一下这组代码的区别") # cat() 是 R 里常用的“把文字输出到屏幕”的函数
```
```{r,results='markup'} cat("比较一下这组代码的区别") ```
  • messagewarning

参数控制是否显示代码中的消息和警告。将它们设置为 FALSE 可以禁止显示消息或警告


  • fig.widthfig.height 这两个参数用于控制图形输出的大小。你可以根据需要调整图形的宽度和高度。
```{r,fig.width = 6, fig.height= 4} # 可自由变换参数试验
plot(mtcars$mpg, mtcars$hp) # 以 mtcars数据中的 mpg列作为 x轴,以hp列为 y轴出散点图
```


4.8 表格:在 R Markdown 中展示数据

表格是数据分析报告中最常见、也最重要的呈现方式之一:无论是数据展示描述性统计,还是最终的研究结果汇报,表格都能用更清晰、可对照的方式把关键信息表达出来。

在 R Markdown 中,你既可以手动插入表格(适合写“概念对照表”),也可以用 R 代码自动生成表格(适合展示真实数据与分析结果)


方式 1:手动制表(适合概念表 / 速查表)

不常用

当你需要呈现“类型对照”“流程清单”“参数说明”时,手动表格最直接。以下是一个 4×3 的示例:

输入:

|  **概念** |  **含义** |  **示例** |
|:---:|:---:|:---:|
| 数据类型 | 单个值的“类别” | `numeric`, `character` |
| 数据结构 | 数据的组织方式 | vector, data.frame |
| 索引 | 取出数据的方法 | `x[1]`, `df$y` |
| 可复现 | 结果可重复生成 | 同一份代码多次 Knit |
概念 含义 示例
数据类型 单个值的“类别” numeric, character
数据结构 数据的组织方式 vector, data.frame
索引 取出数据的方法 x[1], df$y
可复现 结果可重复生成 同一份代码多次 Knit

提示:这种制表方式一般来说用的比较少,因为我们通常想展示已经读写的数据


方式 2:用 knitr::kable() 自动生成表格

常用

在数据分析中,你最常遇到的是“把数据的一部分展示出来”,例如:查看前几行、展示某些列、生成描述性统计表。

R Markdown 中常用 knitr::kable() 把数据对象直接渲染成整洁表格。

补充说明:knitr::kable() 是什么意思?

knitr 是一个扩展包(package)kable() 是它提供的函数。双冒号 :: 表示“从某个包里调用函数”,即 包名::函数名
这样写的好处是:不必先 library(knitr) 也能直接使用,同时能清晰表明函数来源,减少“同名函数冲突”的风险。

下面用 R 自带数据集 mtcars 演示:我们从数据中挑选 6 列常用变量,展示 前 4 行(4 个车型),并为表格添加标题(caption)

# mtcars 是 R 自带示例数据:
# - 每一行代表一种车型(车型名称存放在“行名”里)
# - 每一列代表一个性能指标(变量)

# 选择 6 个常用变量(列)并取前 4 行(行)
# 变量含义:
#   mpg  : Miles/(US) gallon,油耗(每加仑能跑多少英里;越大越省油)
#   cyl  : cylinders,气缸数
#   hp   : gross horsepower,马力(发动机功率)
#   wt   : weight (1000 lbs),车重(单位是“千磅”)
#   am   : transmission,变速箱类型(0 = 自动挡,1 = 手动挡)
#   gear : number of forward gears,前进档位数

tab <- mtcars[1:4, c("mpg", "cyl", "hp", "wt", "am", "gear")]

knitr::kable(
  tab,
  caption = "Table X. mtcars 数据集前 4 行(选择 6 个常用变量)",
  digits = 2  # digits=2 表示:数值列默认保留 2 位小数,便于阅读与对齐
)
Table X. mtcars 数据集前 4 行(选择 6 个常用变量)
mpg cyl hp wt am gear
Mazda RX4 21.0 6 110 2.62 1 4
Mazda RX4 Wag 21.0 6 110 2.88 1 4
Datsun 710 22.8 4 93 2.32 1 4
Hornet 4 Drive 21.4 6 110 3.21 0 3


表格怎么“更像报告”?(kable 常用自定义)

knitr::kable() 可以通过一些常用参数,让输出更清晰、更接近正式报告的表格风格:

  • 加标题(推荐)caption = "Table 1. ..."
    用于说明这张表展示了什么内容,便于引用与阅读。

  • 控制小数位(更整齐)digits = 2
    让数值列默认保留 2 位小数,版面更统一;如果你希望不保留小数,可改为 digits = 0

  • 设置列对齐方式align = c("c","c","c","c","c","c")
    c/l/r 分别表示 居中/左对齐/右对齐;向量长度应与列数一致。

  • 更强的美化(进阶,可选):HTML 输出时常配合 kableExtra
    例如实现表格居中、条纹底色、加粗表头、调整字体大小等。
    本章先掌握 kable() 的基础用法即可;美化会在后续再系统展开。


4.8.1 进阶制表

仅作展示

进阶制表技巧,目前仅作展示使用,暂时不用学习

进阶制表:嵌入行内可视化 (Inline Plots)

普通的表格只能展示数字,而 “Sparklines” (微型图) 可以展示数据的分布趋势。 下面的代码展示了如何结合 dplyr 的数据处理能力和 kableExtra 的绘图功能,在表格单元格中直接绘制 直方图箱线图

核心技巧: 1. 先用 list() 将一列数据折叠进一个单元格。 2. 使用 kbl(escape = FALSE) 允许 HTML 渲染。 3. 使用 column_spec 配合 spec_*** 函数绘图。

library(dplyr)
library(kableExtra)

# 1. 数据准备
iris_summary <- iris %>%
  group_by(Species) %>%
  summarise(
    Sepal_Mean = mean(Sepal.Length),
    Sepal_Dist = list(Sepal.Width),  # 原始数据保留在这里
    Petal_Dist = list(Petal.Length), # 原始数据保留在这里
    Count = n()
  )

# 2. 绘制表格
iris_summary %>%
  mutate(
    Sepal_Dist = "",
    Petal_Dist = ""
  ) %>%
  
  kbl(escape = FALSE, 
      col.names = c("物种", "平均萼片长", "萼片宽分布 (直方图)", "花瓣长分布 (箱线图)", "样本数"),
      align = "c") %>%
  
  # --- 基础美化 ---
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"), 
    full_width = FALSE, 
    position = "center",
    font_size = 16
  ) %>%
  
  column_spec(1, bold = TRUE, color = "#003153") %>%
  
  # 条件格式
  column_spec(2, color = ifelse(iris_summary$Species == "setosa", "#d9534f", "#333"),
              bold = ifelse(iris_summary$Species == "setosa", TRUE, FALSE)) %>%
  
  # --- 嵌入直方图 ---
  column_spec(3, image = spec_hist(iris_summary$Sepal_Dist, 
                                   col = "#003153", 
                                   line_col = "transparent")) %>%
  
  # --- 嵌入箱线图 ---
  column_spec(4, image = spec_boxplot(iris_summary$Petal_Dist, 
                                      col = "#003153", 
                                      fill = "#e6f2ff",
                                      width = 300, 
                                      height = 50)) %>%

  row_spec(0, background = "#f8f9fa", color = "#003153", bold = TRUE)
物种 平均萼片长 萼片宽分布 (直方图) 花瓣长分布 (箱线图) 样本数
setosa 5.006 50
versicolor 5.936 50
virginica 6.588 50

4.9 进阶资源与 AI 辅助

重要

R Markdown 的功能较为丰富,无需也不必机械记忆全部语法细节。在入门阶段,更重要的能力是学会检索定位问题提出清晰的问题。许多实际问题都应在操作过程中逐步掌握,而不是依赖死记硬背。

当遇到不会写的格式、输出异常或代码报错时,可优先通过以下几种方式处理。


1. 查阅指南与速查资料

以下资源适合作为日常查阅的参考材料;除下列链接外,也可根据需要自行搜索其他中英文教程。


2. 视频与操作型学习资源

若更偏好边看边做的学习方式,可优先参考 Bilibili(B站)小红书 等平台上的入门教程。这类资源通常包含完整演示流程,便于快速建立对 R Markdown 工作流的直观理解。

  • 推荐搜索关键词
    • R Markdown 基础教程
    • R Markdown 入门 实战
    • R 语言 论文排版
    • RStudio 新手入门
    • Markdown 入门
    • Quarto 与 R Markdown 区别

3. 如何向 AI 提问? (Prompting Guide)

重要

在本课程的入门阶段,生成式 AI (如 ChatGPT、Gemini、Claude、Kimi 等) 可用于辅助排查报错、理解语法与改进排版。但需要注意,AI 回答的质量高度依赖提问方式。若只给出一句“代码报错了”,通常很难获得可直接执行的解决方案。

更有效的做法,是按照下面的结构组织提问信息。

通用提问结构:角色 + 背景 + 需求 + 原始信息

  • 角色设定:说明希望 AI 以何种身份回答
    例如:R 语言助教 / 数据分析师 / R Markdown 排版助手

  • 具体背景:交代当前任务、软件环境与输出目标
    例如:在 RStudio 中 Knit HTML;正在编写课程作业

  • 核心需求:明确希望 AI 完成什么
    例如:定位报错原因;修改代码;解释语法;优化排版

  • 原始信息:提供足够的上下文材料
    例如:完整代码块;报错信息全文;截图;最小可复现示例


场景 A:忘记语法 / 需要编写新代码

低效问法
“我在写 R Markdown 作业,需要插入一个表格,你告诉我怎么做?”

问题在哪:这类提问仍然过于笼统。AI 无法判断你需要的是 Markdown 原生表格,还是 通过 R 代码生成的表格;也不知道你希望表格呈现几行几列、使用什么表头,以及是否有居中美化HTML 输出等额外要求。缺少这些信息时,往往只能得到较为泛泛的回答。

高效 Prompt(更贴合真实场景)
[角色] 你是一名 R Markdown 排版助教。
[背景] 我正在用 RStudio 编写 .Rmd 作业,需要在正文中插入一个简单 Markdown 表格 (不是用 R 代码生成)
[需求] 请给我一段可直接复制的 Markdown 代码,创建一个 3 行 4 列的表格。
[细节] 表头为:姓名、年龄、学号、成绩;表格内容可使用示例值占位。
[要求] 同时告诉我:如果希望表格在 HTML 输出中更整齐 (如居中或更美观),通常有哪些可行做法?”


场景 B:代码报错 / Knit 失败 (最常见)

低效问法
“我 Knit 失败了,你帮我看看怎么回事。”

问题在哪:这类提问通常缺少三类关键信息:
1)输出格式是什么 (HTML / PDF / Word)
2)控制台中的完整报错信息
3)对应的出错代码块与相关文件路径。
若缺少这些信息,AI 往往只能给出通用建议,难以定位到可执行的修复方案。

高效 Prompt(可直接复制的模板)

  • 背景:我在 RStudio 中将 .Rmd 文件 Knit 为 HTML,过程中报错。
  • 报错信息 (原文粘贴)Error in file(file, "rt") : cannot open the connection
  • 出错位置:错误发生在第 X 个代码块,或提示指向 xxx.Rmd 的第 X 行。
  • 代码片段 (完整粘贴)
```{r, echo=FALSE}
knitr::include_graphics("images/fig1.png")
```
  • 文件结构:相关文件是否真实存在?它位于哪个文件夹?代码中引用的路径是什么?
    例如:images/fig1.png

  • 需求:请判断该报错更可能属于哪一类问题 (如路径错误、文件名拼写错误、工作目录不一致、权限问题等),并给出:
    1)建议优先检查的要点;
    2)修复后的写法,或更稳妥的替代代码。


场景 C:文档美化 / 进阶功能

低效问法
“我想把 R Markdown 做得好看一点,有什么办法?”

问题在哪:目标仍然过于宽泛。AI 不清楚你想优化的是主题风格目录结构代码展示方式,还是版式布局;也不知道你的输出格式是 HTML、PDF 还是 Word。因此,得到的回答往往只是若干泛泛建议,而缺少可直接使用的配置代码。

高效 Prompt(聚焦 YAML 配置,便于直接使用)
[角色] 你是 R Markdown 排版与主题配置助手。
[背景] 我正在用 RStudio 编写 .Rmd 文件,并 Knit 输出 HTML,但目前页面样式较为单调。
[需求] 请帮我生成一段可直接复制的 YAML 头文件 (YAML Header) 配置,用于美化文档。
[具体要求]
1)使用 flatly 主题;
2)添加自动目录 (TOC),并让目录悬浮显示 toc_float
3)开启代码折叠功能 code_folding
[输出要求]:请直接给出完整 YAML 代码,并逐行解释每个参数的作用,以及常见问题 (如缩进、冒号与空格)。”


老师的建议

AI 可以作为高效的辅助工具,但判断与理解仍需要由你自己完成。为了让 AI 真正帮助学习,而不是带来新的混乱,可特别注意以下三点:

  1. 避免直接复制,优先生成“可读代码”
    • AI 输出中常包含占位符 (如 "YOUR_FILE_PATH"、默认参数,或与本机环境不完全匹配的写法,直接运行时往往容易报错。
    • 建议:提问时明确要求:“请逐行加注释,并标明哪些位置需要替换为我自己的路径或文件名。”
  2. 补全关键信息,降低“似是而非”的风险
    • AI 回答的质量高度依赖输入信息。描述不完整时,得到的方案可能看似合理,但实际无法复现。
    • 建议:至少提供以下内容:输出格式 (HTML / Word / PDF)、报错原文 (优先复制文本而非截图)、相关代码块、文件路径,以及必要时的运行环境信息 (如 sessionInfo()
  3. 善用同伴讨论,提高除错效率
    • 在编程学习中,小组讨论与相互除错 (debug) 往往能够更快定位问题。
    • 建议:遇到卡点时,可将“报错信息 + 最小可复现代码 + 目标效果”整理后与同学讨论,这通常有助于更快形成稳定且可迁移的解决经验。

5.0 规范与文献管理

5.0 代码规范与学术引用

掌握基础语法仅是数据分析的起点,编写高质量的代码对于研究的可复现性协作效率至关重要。数据科学项目不仅要求代码能被计算机正确执行,更强调其在同行间(以及未来的复用场景中)可读性可维护性

本节将系统介绍 R 语言社区通用的代码风格规范,并解析如何利用 R Markdown 的自动化参考文献管理功能,构建符合严谨学术标准的分析报告。


5.1 代码风格规范

核心规范

遵循一致的代码风格是保证代码可读性可维护性的基础。
R 语言社区普遍采纳以下三项核心规范:

1. 命名规范:蛇形命名法

变量与函数的命名推荐使用 蛇形命名法 (snake_case),即字符全部小写,单词之间以下划线连接。

  • 推荐student_score, raw_data, fit_model
  • 避免StudentScore (驼峰式,易混淆), student.score (点号在 R 中有特殊含义), s (无明确语义的单字母)

2. 空格规范:运算符留白

为增强视觉清晰度,二元运算符 (如 <-, +, =, ==) 的两侧应保留空格。

  • 推荐x <- 1 + 2
  • 避免x<-1+2 (过于紧凑,难以阅读)

3. 长度限制:控制行宽

单行代码建议控制在 80 个字符以内。若代码过长,应在逗号或运算符后换行,并保持适当缩进。

技巧:代码自动格式化

高效

RStudio 内置了代码样式重构功能。选中代码段后,使用以下快捷键即可自动修正空格、缩进与换行,快速实现代码规范化:

  • Windows: Ctrl + Shift + A
  • Mac: Cmd ⌘ + Shift + A

5.2 注释规范

重要

注释不仅是代码的附属说明,更是分析逻辑的载体。在学术研究与数据科学协作中,高质量的注释应聚焦于解释代码背后的研究意图,而非单纯复述语法功能。

  • 低效注释(语法复述):仅重复代码的字面含义,未能提供增量信息。
```{r}
mean(x)  # 计算 x 的平均值
```
  • 高效注释(逻辑阐释):清晰说明了数据处理的动机、依据或算法逻辑。
```{r}
# 使用平均值填补缺失数据,因为数据分布较为对称
x[is.na(x)] <- mean(x, na.rm = TRUE)
```

核心原则:代码负责呈现 “How” (技术实现),而注释应侧重阐释 “Why” (研究逻辑)


5.3 自动化参考文献管理 (Citations)

在学术论文撰写过程中,参考文献格式的实时调整通常是一项具有挑战性的任务。R Markdown 结合 BibTeX 系统构建了一套自动化的引注方案,实现了文献元数据与排版样式的解耦。相较于传统文字处理软件的人工调整模式,该机制在处理大规模引证与格式切换时具备显著的工程优势。

Step 1 配置文献元数据库 (The .bib File)

自动化引用的核心基础是构建一个以 .bib 为后缀的纯文本数据库 (例如 references.bib)。该文件需存放于当前 R Project 的根目录下。

.bib 文件用于集中存储符合 BibTeX 规范的文献条目。此类结构化的元数据通常可从 Google Scholar、PubMed 等学术搜索引擎或 Zotero、Mendely 等文献管理工具中直接导出,无需人工手动录入。

示例内容 (references.bib):

@article{wickham2014,
  title={Tidy data},
  author={Wickham, Hadley},
  journal={Journal of Statistical Software},
  volume={59},
  number={10},
  year={2014}
}

Step 2 文献库的全局声明

在 R Markdown 文档顶端的 YAML 元数据区域,需利用 bibliography 字段定义文献数据库文件的关联路径。此外,若需采用特定的学术期刊引用规范,可进一步配置 csl (Citation Style Language) 字段,以加载相应的引文格式定义文件。

---
title: "第 1 章:R Markdown 入门"
output: html_document
bibliography: references.bib
csl: apa.csl
---
  • bibliography: 指向你的 .bib 文件路径(建议与 Rmd 同目录,或写相对路径)
  • csl: 是参考文献样式文件(例如 APA、Chicago、Nature 等)
  • 若暂时不需要严格期刊格式,可以先不写 csl,但最终论文/作业通常建议补上

资源获取:CSL 样式定义文件

  • 样式来源:通常从 Zotero Style RepositoryCitation Styles Council 等公共存储库检索并下载符合期刊要求的引文格式 (例如 APA 7th Edition)

  • 存储策略:下载完成后的 .csl 文件建议存放于 R Project 的根目录下 (即与 .Rmd 文档同级)。这种布局有利于简化路径引用逻辑,并确保项目在跨设备迁移时的稳定性。

  • 格式切换机制:若需变更引文风格 (例如从 APA 切换至 Nature 或 GB/T 7714),仅需修改 YAML 区域中 csl 字段指向的目标文件名。渲染引擎将自动重新解析文献数据,并依据新样式的定义实现全局格式的重排。

Step 3 正文引注操作 (In-text Citations)

在文档正文部分,通过调用引用键 (Citation Key) 实现文献的关联引证。引用键需对应 .bib 数据库条目中定义的唯一 ID 标识 (例如前述示例中的 wickham2014)

常用引注语法规范:

  • 括注 (Parenthetical citations):采用 [@wickham2014] 格式。渲染后,引文信息通常被完整封装在括号内,如 (Wickham, 2014)。该方式常用于陈述事实后的文献支撑。
  • 叙述性引注 (Narrative citations):采用 @wickham2014 格式 (不含方括号)。此时作者姓名通常作为句子的主语或逻辑组成部分,如 Wickham (2014) 认为…
  • 多文献联合引用 (Multiple citations):在方括号内利用分号分隔多个引用键,例如 [@wickham2014; @smith2020]

源码与渲染效果对比:

引注类型 Markdown 源码 最终渲染效果示例
标准括注 数据整洁化是基础 [@wickham2014]。 数据整洁化是基础 (Wickham, 2014)。
作者主语 Wickham 系统提出了框架 @wickham2014。 Wickham (2014) 系统提出了框架。
多源引用 相关研究较为丰富 [@key1; @key2]。 相关研究较为丰富 (Key1, 2020; Key2, 2022)。

运行逻辑:在执行 Knit 指令时,Pandoc 转换引擎会自动扫描正文中的所有引用键,并从关联的 .bib 文件中检索对应的元数据。渲染程序不仅会在引注处生成符合 CSL 规范的文本,还会在文档末尾自动汇总并生成完整的参考文献列表 (Reference List)

Step 4 自动化生成参考文献列表 (Bibliography Generation)

在文档的末尾 (或预期的参考文献显示位置) 定义一个相应的标题。通常采用如下格式:

# 参考文献

在执行 Knit 渲染时,渲染引擎 (Pandoc) 会自动识别正文中已调用的引用键,并将对应的条目按选定的 CSL 样式汇总成规范的参考文献列表。该列表通常会自动排列在文档末尾的标题下方。

运行逻辑:在默认设置下,最终生成的列表仅包含正文中实际被引用的文献。若 .bib 数据库中的某些条目未在正文中通过引用键调用,则通常不会出现在最终的参考文献列表中。


5.3.2 进阶:显示未引用的文献 (Nocite)

可选

若需在输出文档中强制展示 .bib 文件中的全部条目 (无论正文是否实际引用),可在 YAML 区域配置 nocite 字段:

---
bibliography: references.bib
nocite: '@*'  # 强制显示文献库中的所有条目
---

5.4 常用引用写法速查

可选 · 速查

下面是课堂最常用的几种引用控制方式(R Markdown/Pandoc 支持):

1) 页码 / 定位信息(常用于书籍或报告)

[@wickham2014, p. 12]

2) 抑制作者名,只显示年份(当作者已在句中出现时)

Wickham 提出…… [-@wickham2014]

3) 同一句中多个引用(注意用分号分隔)

多项研究均支持这一结论 [@wickham2014; @smith2020; @liu2023]

注意:引用键(key)不要乱命名

  • 建议用 作者姓 + 年份:如 wickham2014,便于记忆与检索
  • 若同一作者同一年多篇:可用 wickham2014a, wickham2014b 区分

5.5 文献管理工作流:Zotero × Better BibTeX(推荐)

可选 · 推荐

如果你希望把“引文收集—清洗—导出”做到可持续维护,建议使用:

  • Zotero:管理文献、PDF、笔记、标签
  • Better BibTeX 插件:自动导出 .bib,并保持引用键稳定

一个典型工作流:

  1. 在 Zotero 中建立你的课程/论文文献库(可按章节建立 Collection)
  2. 安装 Better BibTeX 插件
  3. 设置“自动导出(Auto-export)”到项目目录:references.bib
  4. 在 Rmd 中引用:bibliography: references.bib

这样你的 .bib 会随着 Zotero 的更新自动同步,避免“复制粘贴 bib 反复改错”。


5.6 常见错误与排错(Troubleshooting)

可选 · 排错

如果引用不显示 / 参考文献不生成,先检查这四点

1) YAML 是否正确声明了 bibliography
- bibliography: references.bib 路径是否写对(大小写、相对路径)

2) 引用键(key)是否存在且一致
- .bib 里是 @article{wickham2014, ...}
- 正文必须写 [@wickham2014],完全一致(含大小写)

3) 是否真的“引用过”
- 若正文没有任何 [@...],参考文献列表不会生成内容

4) 是否存在非法字符
- .bib 里的 key 建议只用字母数字与下划线
- 避免中文、空格、特殊符号

6.0 本章练习

6.0 动手实战

实战目标

本节实战旨在通过具体任务的拆解,强化以下核心技能在真实数据分析场景中的综合应用:

  • 文档架构配置 (Document Structuring):从初始化环境开始构建完整的 R Markdown 结构,涵盖 YAML 元数据正文叙述代码块的逻辑分层。

  • 基础语法应用 (Markdown Syntax):涵盖多级标题、文本加粗、列表排版、超链接、图像引用及分割线等排版要素的熟练调用。

  • 代码块交互与逻辑调控 (Code Chunk Management):执行基础 R 运算指令,并解析关键代码块参数 (如 evalecho) 对最终报告呈现结果的影响。

  • 工程化项目管理 (Project Management):在 R Project 框架下科学组织文件资源,并利用相对路径 (Relative Path) 实现静态资源 (如本地图片) 的稳定引用与跨平台复现。


6.1 基础任务:复现“学习计划书”

这是一个“照着做”的练习。你需要复制结构复现排版跑通代码

重点不是写得多漂亮,而是把流程跑通、把概念用起来。

6.1.1 任务要求 (Task Specifications)

任务目标涉及在新建的 Exercise_Lab1 项目环境下,构建一份具备完整逻辑结构的 R Markdown 文档。该文档通常应满足以下核心技术要素:

  • 文档属性声明:构建包含标题、作者、日期及输出格式的 **元数据区域** [(YAML Header)]{.note}
  • 结构化层级:文档需包含至少 2 个一级标题、2 个二级标题及 2 个三级标题,以体现清晰的**文档大纲** [(Document Outline)]{.note}
  • 列表编排:至少包含 1 个无序列表与 1 个有序列表,用于展示结构化信息。
  • 静态资源引用:至少包含 1 个外部链接与 1 张图像 (支持本地相对路径或网络 URL 引用)
  • 代码集成与执行:包含至少 2 个代码块,其中 1 个需配置为可执行状态并产生可见输出。
  • 动态文本渲染:至少包含 1 处行内代码,例如调用 r​ Sys.Date() 动态显示日期。

6.1.2 标准化操作流程 (Operational Workflow)

建议遵循以下工程化流程以确保文档的稳定渲染:

Step 1 项目环境构建 (Project Initialisation)
通过 RStudio 菜单栏执行 File -> New Project,创建一个名为 Exercise_Lab1 的新 R Project

Step 2 文档初始化 (Document Creation)
在项目环境下执行 File -> New File -> R Markdown,并将初始标题设定为 “My Study Plan”。文档通常保存为 My_Study_Plan.Rmd

Step 3 静态资源配置 (Resource Anchoring)
- 本地路径模式:建议在项目根目录下新建 img/ 文件夹,并将图像资源存放于此,例如 img/campus.png
- 网络资源模式:获取合法且稳定的图像 URL。

Step 4 模板套用与参数替换 (Template Implementation)
将下方的标准模板导入 .Rmd 编辑器,并将标记为 【需替换】 的占位符更新为具体的分析内容。

建议:在编辑过程中,建议随时点击编辑器上方的 Knit 按钮进行阶段性渲染,以便及时识别并纠正语法错误。生成的 HTML 报告将自动存储在项目的根目录中。

6.1.3 可直接复现的模板(复制后按提示改)

---
title: "My Study Plan"
author: "【需要你修改:你的名字】"
date: "2026-03-19"
output: html_document
---

# 1. 本学期目标

本学期我希望重点提升以下能力:

- 数据处理(Data Wrangling)
- 可视化(Visualisation)
- 报告写作(Reproducible Reporting)


## 1.1 本周小计划(有序列表示例)

1. 安装并打开 RStudio
2. 创建一个 R Project
3. 新建并 Knit 一个 R Markdown
4. 完成今天的练习并提交


## 1.2 资源链接(链接示例)

我会参考 R Markdown 官方速查表:  
[R Markdown Cheatsheet](https://posit.co/resources/cheatsheets/)

---

# 2. 插入图片(本地 or 网络 二选一)

## 2.1 方式 A:本地图片(推荐)

> 先把图片放到项目文件夹的 `img/` 目录下,例如:`img/campus.png`

![【需要你修改:图片说明】](img/campus.png)

## 2.2 方式 B:网络图片(可选)

![R Markdown Logo](https://rmarkdown.rstudio.com/images/hex-rmarkdown.png)

---

# 3. 第一次代码运行

下面我将尝试计算一个圆的面积。假设半径 r = 5,公式为:S = π r^2。  
(注意:这里的 π 在 R 中写作 `pi`。)

```{}
r <- 5
area <- pi * r^2
area
```

## 3.1 代码块选项演示:只展示代码,不运行

这段代码不会执行,但会显示在报告里

```{r,eval = F}
x <- 1:10
mean(x)
```

## 3.2 行内代码示例(Inline R)

今天的日期是:`r​ Sys.Date()`
保留刚才计算圆面积的两位小数 `r​ round(pi*5^2, 2)`

6.2 小挑战任务:我的“入门学习笔记卡片”

这是一个 不给代码 的练习:你需要自己写出来。
难度不高,但需要把第一章的要点组合起来。

6.2.1 任务说明

请新建一个 R Markdown:My_First_R_Report.Rmd,输出 HTML,并完成一份 “学习笔记卡片(Learning Card)”。内容主题自选,例如:

  • “我为什么要学 R?”
  • “本周我学会了哪些 RStudio 操作?”
  • “R Markdown 对我的论文/作业有什么用?”
6.2.2 硬性要求(Checklist)

你的报告必须包含(全部满足才算完成):

  1. YAML:title / author / date / output(HTML)
  2. 排版元素(至少各 1 个):
    • 一级标题 #
    • 二级标题 ##
    • 加粗、斜体(任选其一即可)
    • 无序列表 & 有序列表
    • 分割线 ---
  3. 链接 + 图片
    • 1 个外部链接(URL)
    • 1 张图片(本地相对路径或网络图片都可)
  4. 数学公式(任选一种):
    • 行内公式:例如 $S=\pi r^2$
    • 独立公式:例如 $$S=\pi r^2$$
  5. R 代码块(至少 2 个):
    • 代码块 A:执行并产生输出(例如计算、打印、简单汇总)
    • 代码块 B:体现一个 chunk 选项(echo=FALSEeval=FALSE 二选一)
  6. 行内 R(至少 1 处):例如显示日期、显示一个计算结果等
6.2.3 自检提示(写完后请对照)

常见错误排查(新手高频)

  • Knit 报错但 Console 能跑:优先检查 YAML 三个短横线 是否完整、缩进是否正确
  • 标题不生效:# 后面必须有 空格
  • 图片显示不出来:优先检查 路径是否相对项目根目录,以及文件名大小写是否一致
  • 代码块不运行:代码块格式必须是 {r} ...,括号和花括号不要写错

6.3(可选加分)挑战升级

如果你完成得比较快,可以尝试加 1 个“加分项”(任选一个):

  • 在报告中加入 一个表格(Markdown 表格即可)
  • 在某个代码块里加入 echo=FALSE,让报告更“像正式成果”
  • 用行内 R 自动生成一句话,例如:
    “我今天完成练习的日期是 2026-03-19”