数据挖掘与R语言

第1讲:数据挖掘概述与R语言环境搭建

2026年03月11日

先看看我们能用R做什么

2026年两会政府工作报告的关键词词频——用10来行R代码自动生成:

点击查看R代码
library(wordcloud2)
library(jiebaR)
library(tidytext)
library(here)

text      <- read.csv("report.txt", header = FALSE, sep = "\n")
stopwords <- readLines(here("data/stopwords-zh.txt"), encoding = "UTF-8") |>
  str_trim() |>
  discard(\(x) x == "") |>
  tibble(word = _)

text |>
  pull(V1) |>
  segment(worker()) |>
  tibble(word = _) |>
  unnest_tokens(input = word, output = word) |>
  filter(nchar(word) >= 2, !str_detect(word, "[0-9[:punct:]%]")) |>
  anti_join(stopwords, join_by(word)) |>
  count(word, sort = TRUE) |>
  wordcloud2()

提示

本节课结束后,你可以把这份报告换成任何中文材料——比如想看《红楼梦》里哪个人物出场最多,同样可以轻松实现。我们一步一步来。

本讲内容

  • Part 1:数据挖掘是什么? ——用三个故事说清楚(约20分钟)
  • Part 2:环境搭建 ——安装R和RStudio,处理常见问题(约15分钟)
  • Part 3:RStudio界面 ——四大面板与工作流程(约10分钟)
  • Part 4:R语言初体验 ——从Hello World开始(约25分钟)
  • Part 5:数据读写实战 ——内置数据、包数据、文件导入导出(约20分钟)

Part 1 数据挖掘是什么?

用三个故事说清楚

1.1 故事一:超市货架上的秘密

1990年代,美国沃尔玛的数据分析师发现了一件怪事:

每逢周五傍晚,尿布和啤酒的销量会同时上升。

这两样东西有什么关系?调查后发现:周五下班后,爸爸们受妈妈委托去超市买尿布,顺手也给自己带一箱啤酒回家。

沃尔玛怎么做的? 把尿布和啤酒摆在相邻货架,销量双双提升。

这就是数据挖掘

没有人事先"猜到"这个规律,而是从数百万条交易记录中,让计算机自动找到了这个模式。

数据挖掘:用计算机从大量数据中,自动发现人眼看不出来的、有价值的规律。

1.2 故事二:谷歌如何"预测"流感

2008年:一个看似完美的发现

谷歌工程师发现:某些搜索词(如"流感症状"、"退烧药")的搜索量,与美国疾控中心(CDC)公布的流感病例数高度相关

  • CDC的数据有两周滞后,谷歌数据是实时的
  • 模型在2008年的预测精度令人惊叹
  • 2009年,论文发表在顶级期刊《Nature》上,轰动一时

2012–2013年:模型崩了

预测值比实际感染人数高出近一倍。原因是什么?

警告

谷歌更新了搜索引擎的自动补全功能——只要搜索"头痛",谷歌就自动推荐"流感症状"。搜索量暴增,但实际患病人数并没有增加。

1.2 故事二:谷歌流感的教训

▶️ 查看代码
flowchart LR
    A["用户搜索<br/>头痛"] --> B["谷歌自动补全<br/>推荐流感症状"]
    B --> C["流感症状<br/>搜索量↑↑"]
    C --> D["模型预测:<br/>流感大爆发!"]
    D --> E["实际情况:<br/>没有那么严重"]

    style A fill:#e8f4f8,color:#000
    style B fill:#fff3cd,color:#000
    style C fill:#f8d7da,color:#000
    style D fill:#f8d7da,color:#000
    style E fill:#d4edda,color:#000

flowchart LR
    A["用户搜索<br/>头痛"] --> B["谷歌自动补全<br/>推荐流感症状"]
    B --> C["流感症状<br/>搜索量↑↑"]
    C --> D["模型预测:<br/>流感大爆发!"]
    D --> E["实际情况:<br/>没有那么严重"]

    style A fill:#e8f4f8,color:#000
    style B fill:#fff3cd,color:#000
    style C fill:#f8d7da,color:#000
    style D fill:#f8d7da,color:#000
    style E fill:#d4edda,color:#000

核心教训:相关 ≠ 因果

搜索量和流感相关,但搜索量上升不是因为更多人生病——而是谷歌改了产品功能。环境一变,相关关系就消失了。

做数据挖掘,永远要追问:这个规律背后有没有真实的因果逻辑?

1.3 故事三:Netflix 的推荐算法

Netflix 知道你下一部想看什么——往往比你自己还准。

它是怎么做到的?

  • 不问你"喜欢什么类型"——这种自我报告不准确
  • 而是观察你的行为:看了什么、什么时候暂停、快进了哪里、看了几分钟后关掉
  • 再把你和数百万个行为模式相似的用户对比:"和你一样的人,最后都看了这部"

无监督挖掘

  • 把用户按行为模式自动分组(聚类),不预设答案,让数据自己说话

有监督预测

  • 根据历史行为,预测你点击某部片子的概率(分类 / 回归)

注记

2006年,Netflix 举办百万美元算法竞赛,要求推荐准确率提升10%,极大推动了现代推荐系统的发展。

1.4 从故事到定义

数据挖掘的定义

大量数据中,通过计算机自动分析,发现对特定问题有价值的规律、模式或预测模型的过程。

— Berry & Linoff (2000)

三个故事对应三类核心任务:

故事 发现了什么 对应方法
沃尔玛尿布啤酒 商品之间的共现规律 关联规则(无监督)
谷歌流感趋势 用搜索行为预测感染人数 回归预测(有监督)
Netflix 推荐 用户分组 + 点击预测 聚类 + 分类(两者都有)

1.5 数据挖掘 vs. 传统统计

两者都在分析数据,区别在于出发点

传统统计

先有假设,再用数据验证

"我认为吸烟导致肺癌,让我设计实验来证明"

  • 假设驱动,变量少
  • 目标:推断、解释、检验
  • 典型工具:t检验、方差分析、回归

数据挖掘

先有数据,让数据告诉你规律

"我有100万条交易记录,里面藏着什么?"

  • 数据驱动,变量多
  • 目标:预测、分类、发现模式
  • 典型工具:决策树、神经网络、聚类

注记

数据挖掘不是取代统计学,而是借助计算能力处理更大规模、更复杂的任务。本课程两者都会用到。

1.6 数据挖掘的基本流程

▶️ 查看代码
flowchart LR
    A["① 理解问题<br/>业务目标是什么?"] --> B["② 获取数据<br/>有哪些数据可用?"]
    B --> C["③ 清洗准备<br/>处理缺失与异常"]
    C --> D["④ 建立模型<br/>选择算法训练"]
    D --> E["⑤ 评估模型<br/>在新数据上表现?"]
    E --> F["⑥ 部署应用<br/>集成业务持续监测"]
    F -.->|"环境变化,重新来过"| A

    style A fill:#1a3a5c,color:#fff
    style B fill:#2e5984,color:#fff
    style C fill:#375623,color:#fff
    style D fill:#843c0c,color:#fff
    style E fill:#4b2e83,color:#fff
    style F fill:#117a65,color:#fff

flowchart LR
    A["① 理解问题<br/>业务目标是什么?"] --> B["② 获取数据<br/>有哪些数据可用?"]
    B --> C["③ 清洗准备<br/>处理缺失与异常"]
    C --> D["④ 建立模型<br/>选择算法训练"]
    D --> E["⑤ 评估模型<br/>在新数据上表现?"]
    E --> F["⑥ 部署应用<br/>集成业务持续监测"]
    F -.->|"环境变化,重新来过"| A

    style A fill:#1a3a5c,color:#fff
    style B fill:#2e5984,color:#fff
    style C fill:#375623,color:#fff
    style D fill:#843c0c,color:#fff
    style E fill:#4b2e83,color:#fff
    style F fill:#117a65,color:#fff

警告

数据清洗准备往往占总工作量的 60–80%。 建模本身不是最难的部分——把数据整理成能用的形态,才是真正费时费力的地方。

Part 2 环境搭建

安装R和RStudio,处理常见问题

2.1 R 与 RStudio 的关系

R 语言

  • 真正执行计算的引擎
  • 好比汽车的发动机
  • 本身界面简陋,很少直接用
  • 必须先安装

🔗 https://cran.r-project.org/

RStudio

  • R 的集成开发环境(IDE)
  • 好比汽车的驾驶舱
  • 提供编辑器、可视化、项目管理
  • 必须后安装(依赖R引擎)

🔗 https://posit.co/download/rstudio-desktop/

重要

顺序不能反:先装R,再装RStudio。

RStudio 启动时会自动寻找 R 的安装位置。如果 R 还没装,RStudio 找不到引擎就无法工作。

2.2 安装步骤

第一步:安装 R

  1. 访问 https://cran.r-project.org/,点击对应系统的链接
    • Windows → Download R for Windows → base → 下载运行
    • macOS → Download R for macOS → M系列芯片选 arm64,Intel 选 x86_64
  2. 全程默认设置,一路点"下一步"

第二步:安装 RStudio

  1. 访问 https://posit.co/download/rstudio-desktop/
  2. 点击下载(网站自动识别系统),运行安装包,默认设置

验证安装

打开 RStudio,在左下角 Console 输入 1 + 1,按回车,看到 [1] 2 即成功 ✅

2.3 常见问题排查

问题现象 原因 解决方法
RStudio 找不到 R 先装了 RStudio 再装 R 重装 RStudio,或在设置里指定 R 路径
安装包很慢或超时 默认服务器在国外 换国内镜像(见下方)
安装包提示权限不足 没有管理员权限 右键"以管理员身份运行"RStudio
macOS 提示无法验证开发者 系统安全设置 系统设置 → 隐私与安全性 → 仍要打开
中文乱码 编码设置问题 Tools → Global Options → Code → UTF-8
# 安装包很慢?切换到国内镜像(推荐清华大学)
options(repos = c(CRAN = "https://mirrors.tuna.tsinghua.edu.cn/CRAN/"))

# 之后正常安装即可
install.packages("tidyverse")

Part 3 熟悉 RStudio 界面

四大面板与工作流程

3.1 四大面板一览

▶️ 查看代码
flowchart TD
    subgraph rstudio["RStudio 界面"]
        A["📝 左上:Source Editor(脚本编辑区)<br/>在这里写代码并保存为 .R 文件<br/>支持语法高亮、自动补全、括号匹配"]
        B["⌨️ 左下:Console(控制台)<br/>代码在这里执行,结果在这里显示<br/>也可以直接在这里输入命令"]
        C["🗂️ 右上:Environment / History<br/>Environment:所有已创建的变量和数据<br/>History:所有执行过的命令"]
        D["📊 右下:Files / Plots / Help<br/>文件管理、图形预览、帮助文档"]
    end

    style A fill:#1a3a5c,color:#fff
    style B fill:#375623,color:#fff
    style C fill:#843c0c,color:#fff
    style D fill:#4b2e83,color:#fff

flowchart TD
    subgraph rstudio["RStudio 界面"]
        A["📝 左上:Source Editor(脚本编辑区)<br/>在这里写代码并保存为 .R 文件<br/>支持语法高亮、自动补全、括号匹配"]
        B["⌨️ 左下:Console(控制台)<br/>代码在这里执行,结果在这里显示<br/>也可以直接在这里输入命令"]
        C["🗂️ 右上:Environment / History<br/>Environment:所有已创建的变量和数据<br/>History:所有执行过的命令"]
        D["📊 右下:Files / Plots / Help<br/>文件管理、图形预览、帮助文档"]
    end

    style A fill:#1a3a5c,color:#fff
    style B fill:#375623,color:#fff
    style C fill:#843c0c,color:#fff
    style D fill:#4b2e83,color:#fff

提示

推荐工作流:在 Source Editor 写代码 → Ctrl+Enter 发送到 Console 执行 → 在 Environment 确认结果 → 在 Plots 查看图形。

3.2 常用快捷键

操作 Windows / Linux macOS
运行当前行 / 选中代码 Ctrl + Enter Cmd + Enter
运行整个脚本 Ctrl + Shift + Enter Cmd + Shift + Enter
插入赋值符号 <- Alt + - Option + -
注释 / 取消注释 Ctrl + Shift + C Cmd + Shift + C
代码自动补全 Tab Tab
查看函数帮助 F1?函数名 F1?函数名
新建脚本 Ctrl + Shift + N Cmd + Shift + N
清空 Console Ctrl + L Ctrl + L

注记

现在就试试:新建脚本(Ctrl+Shift+N),输入 1 + 1,按 Ctrl+Enter 运行。

Part 4 R 语言初体验

从 Hello World 开始

4.1 第一行代码:Hello World

学任何编程语言,第一行代码都是惯例:

print("Hello, World!")
[1] "Hello, World!"

在 R 里,print() 可以省略,直接写字符串也会输出:

"Hello, World!"
[1] "Hello, World!"
"欢迎来到数据挖掘课!"
[1] "欢迎来到数据挖掘课!"

注释:写给人看的文字

# 开头的内容是注释——R 会完全忽略它,但对阅读代码的人很重要。养成写注释的习惯,未来的你会感谢现在的你。

# 这是我的第一行 R 代码
print("数据挖掘,开始!")
[1] "数据挖掘,开始!"

4.2 R 作为计算器

100 + 200
[1] 300
1024 / 4
[1] 256
3^10       # 3的10次方
[1] 59049
sqrt(144)  # 平方根,结果是12
[1] 12
# R 遵循数学运算优先级
2 + 3 * 4    # 先乘后加,结果是14
[1] 14
(2 + 3) * 4  # 括号优先,结果是20
[1] 20

提示

在 Console 里直接输入计算,就像用计算器。但如果想保存和重复使用,要写在脚本里。

4.3 代码格式:换行和空格自由吗?

初学者常有疑问:换行和空格有规定吗?

答案:基本上随意,看你喜好。 R 会自动忽略代码中多余的空格,下面三种写法完全等价:

x <- 1 + 2
x<-1+2
x   <-   1   +   2

唯一需要注意的是换行时机。下面这样会出问题

x <- 1   # R 认为这行已经结束
+ 2      # 这变成了另一个独立的表达式

如果想跨行写,把运算符放在行尾,R 就知道还没结束:

x <- 1 +  # 行尾有运算符,R 等你继续
     2
x
[1] 3

4.4 如果我真的想保留空格怎么办?

R 忽略的是代码层面的空格,但字符串内部的空格会原样保留:

# 代码里的空格怎么写都行
name <- "张   三"   # 但引号内的空格会完整保留
name
[1] "张   三"
nchar(name)         # 长度是4,不是2
[1] 5
# 比较一下:有空格 vs. 没空格
a <- "hello world"
b <- "helloworld"
a == b   # 不相等!空格是字符串内容的一部分
[1] FALSE

提示

记住这个区别:代码排版随意,字符串内容要精确。引号里写的是什么,R 就存什么。

4.5 犯错是正常的——认识常见报错

别怕出错!

不只是初学者,资深程序员每天也在犯错。代码的好处是:改起来极其容易,不像现实中的决策那么难以撤回。看到红色报错信息,不是失败,是 R 在告诉你哪里需要修正。

错误类型 错误示例 正确写法
该加引号没加 name <- 张三 name <- "张三"
不该加引号加了 "mean"(x) mean(x)
引号不配对 "Hello "Hello"
用了中文引号 name <- “张三” name <- "张三"
用了中文逗号 c(1,2,3) c(1, 2, 3)
括号不配对 mean(c(1, 2, 3) mean(c(1, 2, 3))

4.6 变量赋值

每次都重新输入数字很麻烦,可以把值存到一个变量里:

# <- 是赋值符号(快捷键:Alt + -)
身高 <- 175
体重 <- 68

身高
[1] 175
体重
[1] 68
  • 用变量计算BMI值
# 用变量做计算
bmi <- 体重 / (身高 / 100)^2
bmi
[1] 22.2
  • 这样做的好处是,计算不同的BMI只需要修改变量值,不需要修改全部代码。
# 变量也可以存文字
名字 <- "张三"
课程 <- "数据挖掘"

paste(名字, "正在学习", 课程)
[1] "张三 正在学习 数据挖掘"

注记

一旦给变量赋值,R就会将变量值保存在环境里(Environment),后面随时可以调用。

  • 还可以给已存在的变量重新赋值
a <- 7
a
[1] 7
a <- a + 3
a
[1] 10

4.7 向量:一次处理一组数据

现实中面对的不是一个数,而是一列数据

成绩 <- c(85, 92, 78, 96, 88, 73, 91)

mean(成绩)   # 平均分
[1] 86.1
max(成绩)    # 最高分
[1] 96
min(成绩)    # 最低分
[1] 73
# 向量化运算:对每个元素自动逐一判断,无需写循环
成绩 >= 90           # 每人是否达到优秀线?
[1] FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE
成绩[成绩 >= 90]     # 筛选出达到优秀线的成绩
[1] 92 96 91

提示

成绩 >= 90 自动对7个数逐一判断,不需要写循环。向量化运算是 R 高效处理数据的核心特性。

4.8 小例子:班级成绩分析

把上面学到的东西组合起来,做一个完整的小分析:

姓名 <- c("张三", "李四", "王五", "赵六", "陈七", "吴八", "周九")
成绩 <- c(85, 92, 78, 96, 88, 73, 91)

cat("平均分:", mean(成绩), "\n")
平均分: 86.1 
cat("最高分:", max(成绩), "——", 姓名[which.max(成绩)], "\n")
最高分: 96 —— 赵六 
cat("最低分:", min(成绩), "——", 姓名[which.min(成绩)], "\n")
最低分: 73 —— 吴八 
优秀 <- 成绩 >= 90
cat("优秀学生:", paste(姓名[优秀], collapse = "、"), "\n")
优秀学生: 李四、赵六、周九 
cat("优秀率:", mean(优秀) * 100, "%\n")
优秀率: 42.9 %

注记

which.max() 返回最大值的位置,姓名[which.max(成绩)] 就是找到最高分对应的名字。这种"按条件筛选"的思路,在数据挖掘中无处不在。

Part 5 数据读写实战

内置数据 → 包数据 → 文件导入导出

5.1 从内置数据开始:mtcars

R 自带了很多经典数据集,可以直接使用,无需下载:

data(mtcars)
head(mtcars, 5)   # 显示前5行
                   mpg cyl disp  hp drat   wt qsec vs am gear carb
Mazda RX4         21.0   6  160 110 3.90 2.62 16.5  0  1    4    4
Mazda RX4 Wag     21.0   6  160 110 3.90 2.88 17.0  0  1    4    4
Datsun 710        22.8   4  108  93 3.85 2.32 18.6  1  1    4    1
Hornet 4 Drive    21.4   6  258 110 3.08 3.21 19.4  1  0    3    1
Hornet Sportabout 18.7   8  360 175 3.15 3.44 17.0  0  0    3    2

注记

mtcars 是1974年《Motor Trend》杂志的32辆汽车数据,包含油耗(mpg)、马力(hp)、车重(wt)等指标。虽然数据很老,但作为教学示例非常经典。

5.1 探索 mtcars 数据

nrow(mtcars)     # 有多少行?
[1] 32
ncol(mtcars)     # 有多少列?
[1] 11
names(mtcars)    # 变量名叫什么?
 [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear"
[11] "carb"
# 快速统计摘要
summary(mtcars[, c("mpg", "hp", "wt")])
      mpg             hp              wt      
 Min.   :10.4   Min.   : 52.0   Min.   :1.51  
 1st Qu.:15.4   1st Qu.: 96.5   1st Qu.:2.58  
 Median :19.2   Median :123.0   Median :3.33  
 Mean   :20.1   Mean   :146.7   Mean   :3.22  
 3rd Qu.:22.8   3rd Qu.:180.0   3rd Qu.:3.61  
 Max.   :33.9   Max.   :335.0   Max.   :5.42  

5.2 包数据:企鹅数据集

palmerpenguins 包提供了一份更有趣的真实数据:

install.packages("palmerpenguins")  # 只需安装一次
library(palmerpenguins)
head(penguins, 5)
# A tibble: 5 × 8
  species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
  <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
1 Adelie  Torgersen           39.1          18.7               181        3750
2 Adelie  Torgersen           39.5          17.4               186        3800
3 Adelie  Torgersen           40.3          18                 195        3250
4 Adelie  Torgersen           NA            NA                  NA          NA
5 Adelie  Torgersen           36.7          19.3               193        3450
# ℹ 2 more variables: sex <fct>, year <int>

注记

penguins 包含南极洲三个岛屿上344只企鹅的测量数据,是近年来最受欢迎的教学数据集之一。

5.2 探索企鹅数据

nrow(penguins)          # 多少只企鹅?
[1] 344
table(penguins$island)  # 三个岛各有多少只?

   Biscoe     Dream Torgersen 
      168       124        52 
# 各种类企鹅的平均体重
tapply(penguins$body_mass_g, penguins$species, mean, na.rm = TRUE)
   Adelie Chinstrap    Gentoo 
     3701      3733      5076 

5.3 导出数据

# 导出为 CSV(最通用,任何软件都能打开)
write.csv(penguins, "penguins.csv", row.names = FALSE)

# 导出为 Excel
install.packages("writexl")   # 只需安装一次
library(writexl)
write_xlsx(penguins, "penguins.xlsx")

提示

row.names = FALSE:不把行号写进去。R 默认会把 1、2、3… 这样的行号写成一列,通常不需要。

5.4 重新读入数据

# 读入 CSV
penguins2 <- read.csv("penguins.csv")
nrow(penguins2)       # 应该还是 344
head(penguins2, 3)
# 读入 Excel
library(readxl)
penguins3 <- read_excel("penguins.xlsx")
nrow(penguins3)

文件在哪里?

R 默认在工作目录下读写文件。在 Console 运行 getwd() 查看,或通过菜单 Session → Set Working Directory 修改。

5.5 完整数据操作流程回顾

library(palmerpenguins)
library(writexl)
library(readxl)

# 探索
head(penguins)
summary(penguins)

# 分析:各种类企鹅的平均体重
tapply(penguins$body_mass_g, penguins$species, mean, na.rm = TRUE)

# 导出
write.csv(penguins, "penguins.csv", row.names = FALSE)
write_xlsx(penguins, "penguins.xlsx")

# 重新读入验证
penguins2 <- read.csv("penguins.csv")
nrow(penguins2)  # 应该还是 344

注记

加载 → 探索 → 分析 → 保存 → 读取——这个闭环贯穿整个课程,后续每个案例都遵循这个节奏。

本讲小结

  • 数据挖掘的本质:用计算机从大量数据中自动发现规律。沃尔玛找到了尿布和啤酒的关联,Netflix 学会了预测你的喜好。

  • 最重要的警示:相关不等于因果。谷歌流感的失败告诉我们,环境一变,没有因果支撑的相关关系就会崩掉。

  • 工具链:R 是引擎,RStudio 是驾驶舱。先装 R,再装 RStudio。遇到安装问题对照排查表处理。

  • 代码格式:换行和空格很自由,R 会自动忽略;字符串内部的空格会原样保留。犯错是正常的,认识常见报错类型,改起来很快。

  • 数据读写:内置数据和包数据直接加载,用 write.csv() / write_xlsx() 导出,用 read.csv() / read_excel() 读回来。

课后练习

基础练习(必做)

  1. 安装 R 和 RStudio,在 Console 运行 print("Hello World!"),截图保存
  2. 创建一个向量,记录你本周每天的睡眠时长(7个数),计算平均值、最长和最短
  3. 加载 penguins 数据,回答:有多少只 Chinstrap 企鹅?Gentoo 企鹅的平均翼展是多少?

进阶挑战(选做)

  1. penguins 数据导出为 CSV 和 Excel,再分别读回来,用 nrow() 验证行数一致
  2. mtcars 数据找出所有 mpg 超过 25 的车型,输出名称和 mpg
  3. 故意写几行有错误的代码(引号不配对、用中文逗号等),观察报错信息长什么样

下讲预告

第2讲:R 语言的数据类型与对象

  • 六种基本数据类型:数值、字符、逻辑
  • 四种核心数据对象:向量、矩阵、数据框、列表
  • 因子:处理分类变量的正确方式
  • 实战:用 penguins 数据集练习各类对象操作

谢谢!

第1讲:数据挖掘概述与R语言环境搭建


"所有模型都是错的,但有些是有用的。"

— George Box,统计学家


朱 奇 | 锦城大学 • 财会学院