R 语言教程

什么是 R 语言?

R 是一种用于统计计算与数据可视化的开源编程语言,由 Ross Ihaka 和 Robert Gentleman 于 1995 年创建,现由 R 基金会维护。R 在数据分析、统计建模、机器学习与学术研究领域应用广泛。

R 语言的核心特点

  • 统计强项:内置大量统计函数与概率分布
  • 可视化:ggplot2 等绘图系统全球闻名
  • 数据分析:数据框、矩阵等数据结构贴合数据分析场景
  • 包生态:CRAN 上有 2 万+ 扩展包
  • 免费开源:跨平台(Windows/macOS/Linux)

R 能做什么

  • 数据清洗与统计分析
  • 数据可视化(报表、仪表盘)
  • 机器学习与预测建模
  • 生物信息学、金融分析
  • 学术研究中的统计检验

第一个 R 程序

# 交互式或脚本运行
print("Hello, R!")

# 基本运算
x <- 10
y <- 20
print(x + y)   # 30

开发环境

RStudio: 最流行的 R IDE(免费)
R Console: 命令行交互
Jupyter: 通过 IRkernel 使用
VS Code: R 插件

R 环境安装

R 环境安装

安装 R 语言与 RStudio 是开始 R 开发的第一步。

1. 安装 R

# Windows
下载 https://cran.r-project.org/bin/windows/base/
双击安装,默认路径 C:\\Program Files\\R\\R-x.x.x

# macOS
下载 dmg 安装包安装

# Linux (Ubuntu)
sudo apt update
sudo apt install r-base

# 验证
R --version

2. 安装 RStudio(推荐 IDE)

下载 https://posit.co/download/rstudio-desktop/
安装后打开,自动识别已安装的 R

3. RStudio 界面

左上: 脚本编辑器(写代码)
左下: Console(交互执行)
右上: 环境/历史
右下: 文件/绘图/包/帮助

4. 安装扩展包

# 从 CRAN 安装
install.packages("ggplot2")
install.packages("dplyr")

# 从 Bioconductor 安装(生物信息)
if (!require("BiocManager", quietly = TRUE))
    install.packages("BiocManager")
BiocManager::install("DESeq2")

# 加载包
library(ggplot2)

5. 第一个脚本

# hello.R
message("Hello, R!")
x <- 1:10
print(mean(x))   # 5.5

# 运行
Rscript hello.R

6. 常见问题

  • 安装包慢:设置国内镜像(清华/中科大 CRAN 镜像)
  • R 找不到:RStudio Tools → Global Options 指定路径
  • 权限问题:Windows 避免装在需要管理员权限的目录

R 基础语法

R 基础语法

R 的语法简洁,以赋值、向量化计算为核心。

赋值

# 三种赋值方式(推荐 <-)
x <- 10
y = 20          # 也可用 = 
10 -> z         # 向右赋值

# 打印
print(x)
print(x + y + z)

注释

# 这是注释
# 用 # 号开头
print("R 中 # 用于注释")

变量命名

my_var <- 1          # 小写+下划线
myVar <- 2           # 驼峰
.隐藏变量 <- 3        # 点开头(隐藏)
# 不能以数字开头
# 区分大小写: Name 和 name 不同

向量(基本单位)

# c() 创建向量
v <- c(1, 2, 3, 4, 5)
print(v)

# 序列
s1 <- 1:10           # 1 到 10
s2 <- seq(1, 10, by = 2)   # 1,3,5,7,9
s3 <- rep(3, 5)      # 3,3,3,3,3

# 向量运算(自动逐元素)
a <- c(1, 2, 3)
b <- c(10, 20, 30)
print(a + b)         # 11 22 33
print(a * 2)         # 2 4 6

输出

print("简单输出")
cat("拼接", "输出", "文本\n")   # cat 不自动换行
sprintf("格式化: %d", 42)       # "格式化: 42"

基础函数

sum(1:10)          # 55 求和
mean(c(1,2,3))     # 2 均值
median(c(1,2,3))   # 2 中位数
sd(c(1,2,3))       # 标准差
max(c(1,5,3))      # 5
min(c(1,5,3))      # 1
length(c(1,2,3))   # 3 长度

R 注释

R 注释

注释帮助理解代码,R 支持单行注释与块注释技巧。

单行注释

# 这是单行注释
x <- 5  # 行尾注释也可

# 打印变量
print(x)

块注释技巧

# R 没有原生多行注释,但可用 if(FALSE) 包裹
if (FALSE) {
  # 这段代码不会执行
  # 相当于块注释
  complicated_function()
}

注释的实践

# 1. 说明"为什么"而非"是什么"
# 将营收标准化到 0-1(避免量纲影响)
normalized <- (revenue - min(revenue)) / 
              (max(revenue) - min(revenue))

# 2. 标注 TODO
# TODO: 后续改为读取数据库

# 3. 引用来源
# 公式来源: ISLR 第 3 章,式(3.4)

Roxygen 文档注释(包开发)

# 开发 R 包时用 roxygen2 格式
#' 计算平均值
#'
#' @param x 数值向量
#' @return 平均值
#' @examples
#' mean2(c(1, 2, 3))
mean2 <- function(x) {
  mean(x)
}

注释的注意事项

1. 不要注释明显的内容(x <- 5 # 赋值)
2. 更新代码时同步更新注释
3. 用注释分隔代码块(# ---- 数据加载 ----)

R 基础运算

R 基础运算

R 支持算术、比较、逻辑等运算符,并擅长向量化运算。

算术运算符

+   加法       -   减法
*   乘法       /   除法
^   幂         %%  取余
%/% 整除

10 / 3      # 3.333333
10 %/% 3    # 3
10 %% 3     # 1
2^10        # 1024

向量化运算

a <- c(1, 2, 3)
b <- c(4, 5, 6)

a + b       # 5 7 9
a * b       # 4 10 18
a^2         # 1 4 9
sqrt(c(1, 4, 9))   # 1 2 3
log(c(1, 10, 100)) # 对数

# 循环利用(长度不同时自动重复)
c(1, 2) + c(10, 20, 30, 40)   # 11 22 31 42

比较运算符

==   等于      !=   不等于
>    大于      <    小于
>=   大于等于   <=   小于等于

5 > 3           # TRUE
c(1, 2) == c(1, 3)   # TRUE FALSE

逻辑运算符

&    元素级与
|    元素级或
!    非
&&   标量与(短路)
||   标量或(短路)

x <- c(TRUE, FALSE, TRUE)
y <- c(TRUE, TRUE, FALSE)
x & y        # TRUE FALSE FALSE
x | y        # TRUE TRUE TRUE
!x           # FALSE TRUE FALSE

# 元素级:返回向量;标量:只取第一个
TRUE && FALSE      # FALSE
c(TRUE, TRUE) && c(FALSE, FALSE)  # FALSE(只看第一个)

数学函数

abs(-5)        # 5
round(3.14159, 2)  # 3.14
floor(3.7)     # 3
ceiling(3.2)   # 4
exp(1)         # 2.718282
pi             # 3.141593

矩阵运算

m1 <- matrix(1:4, nrow = 2)
m2 <- matrix(5:8, nrow = 2)
m1 + m2        # 元素加法
m1 %*% m2      # 矩阵乘法
t(m1)          # 转置

R 数据类型

R 数据类型

R 的基本数据类型包括数值、整数、复数、逻辑、字符与因子。

基本类型

# 数值型(默认 double)
num <- 3.14
class(num)        # "numeric"

# 整数型(加 L)
int <- 42L
class(int)        # "integer"

# 复数
com <- 2 + 3i
class(com)        # "complex"

# 逻辑
logi <- TRUE
class(logi)       # "logical"

# 字符
str <- "Hello"
class(str)        # "character"

类型判断与转换

# 判断
is.numeric(3.14)    # TRUE
is.character("a")   # TRUE
is.logical(TRUE)    # TRUE

# 转换
as.numeric("123")   # 123
as.character(123)   # "123"
as.integer(3.9)     # 3(截断)
as.logical(1)       # TRUE
as.logical(0)       # FALSE

NA 与 NULL

# NA:缺失值
x <- c(1, 2, NA, 4)
is.na(x)           # FALSE FALSE TRUE FALSE
sum(x, na.rm = TRUE)   # 7 忽略缺失

# NULL:不存在
y <- NULL
is.null(y)         # TRUE

因子(Factor)

# 分类变量
gender <- factor(c("男", "女", "男"))
levels(gender)      # "男" "女"
table(gender)       # 频数统计

# 有序因子
grade <- factor(c("低", "高", "中"),
                levels = c("低", "中", "高"),
                ordered = TRUE)

数据结构总览

向量 Vector      一维,同类型
矩阵 Matrix      二维,同类型
数组 Array       多维,同类型
列表 List        一维,可不同类型
数据框 Data Frame  二维,每列可不同类型(最常用)
因子 Factor      分类变量

R 判断语句

R 判断语句

R 使用 if、if-else、ifelse 与 switch 实现条件逻辑。

if 语句

score <- 85

if (score >= 60) {
  print("及格")
}

if-else 语句

if (score >= 90) {
  print("优秀")
} else if (score >= 60) {
  print("及格")
} else {
  print("不及格")
}

ifelse(向量化)

# 向量化的条件判断,返回向量
scores <- c(45, 78, 92, 55)
results <- ifelse(scores >= 60, "及格", "不及格")
print(results)   # "不及格" "及格" "及格" "不及格"

# 嵌套 ifelse
grades <- ifelse(scores >= 90, "A",
          ifelse(scores >= 80, "B",
          ifelse(scores >= 70, "C", "D")))

switch 语句

# 根据索引或值选择
choice <- "b"

switch(choice,
  a = print("选择了 A"),
  b = print("选择了 B"),
  c = print("选择了 C"),
  print("默认选项")
)

逻辑条件组合

age <- 25
has_id <- TRUE

if (age >= 18 && has_id) {
  print("允许进入")
}

if (age < 18 || !has_id) {
  print("禁止进入")
}

缺失值判断

x <- NA

if (is.na(x)) {
  print("x 是缺失值")
} else if (x > 0) {
  print("x 是正数")
} else {
  print("x 是负数或零")
}

R 循环

R 循环

R 提供 for、while、repeat 三种循环,但推荐优先使用向量化与 apply 家族。

for 循环

# 遍历向量
for (i in 1:5) {
  print(i)
}

# 遍历值
fruits <- c("苹果", "香蕉", "橙子")
for (f in fruits) {
  print(f)
}

# 带索引
for (i in seq_along(fruits)) {
  print(paste(i, fruits[i]))
}

while 循环

count <- 0
while (count < 5) {
  print(count)
  count <- count + 1
}

repeat 循环

# repeat 至少执行一次,需手动 break
x <- 1
repeat {
  print(x)
  x <- x + 1
  if (x > 3) break
}

break 与 next

# break:退出循环
for (i in 1:10) {
  if (i == 5) break
  print(i)          # 1 2 3 4
}

# next:跳过本次(类似 continue)
for (i in 1:10) {
  if (i %% 2 == 0) next
  print(i)          # 1 3 5 7 9
}

apply 家族(更 R 风格)

m <- matrix(1:12, nrow = 3)

apply(m, 1, sum)      # 按行求和
apply(m, 2, mean)     # 按列求均值

lapply(list(1:3, 4:6), sum)   # 返回列表
sapply(list(1:3, 4:6), sum)   # 返回向量

# 遍历数据框列
df <- data.frame(a = 1:3, b = 4:6)
sapply(df, mean)      # a=2 b=5

向量化的优势

# 避免循环,直接向量运算(快很多)
x <- 1:100000
y <- x * 2           # 向量化,无循环

# for 循环写法(慢,不推荐)
y <- numeric(100000)
for (i in 1:100000) y[i] <- x[i] * 2

R 函数

R 函数

函数是 R 代码复用的核心,支持默认参数、匿名函数等特性。

定义函数

# 基本函数
add <- function(a, b) {
  result <- a + b
  return(result)
}
print(add(3, 5))   # 8

# 简写(最后一行自动返回)
multiply <- function(a, b) a * b
print(multiply(3, 4))   # 12

默认参数

greet <- function(name, prefix = "你好") {
  paste(prefix, name)
}

greet("张三")            # "你好 张三"
greet("李四", "早上好")   # "早上好 李四"

可变参数(...)

sum_all <- function(...) {
  args <- list(...)
  sum(unlist(args))
}

sum_all(1, 2, 3)         # 6
sum_all(1, 2, 3, 4, 5)   # 15

命名参数与位置参数

f <- function(a, b, c) a + b + c

f(1, 2, 3)              # 位置参数
f(c = 3, a = 1, b = 2)  # 命名参数(顺序可乱)

匿名函数

# 一次性使用,不命名
result <- sapply(1:5, function(x) x^2)
print(result)   # 1 4 9 16 25

# 配合 apply
m <- matrix(1:9, nrow = 3)
apply(m, 1, function(row) max(row))

作用域

global_var <- 10   # 全局

test <- function() {
  local_var <- 20   # 局部
  print(global_var) # 可读全局
  # global_var <- 30  # 这样是新建局部变量
}
test()
# print(local_var)  # 报错:找不到

函数作为参数

apply_twice <- function(f, x) {
  f(f(x))
}
apply_twice(function(v) v * 2, 5)   # 20

R 字符串

R 字符串

R 中字符串使用双引号或单引号,提供丰富的字符串处理函数。

创建字符串

s1 <- "Hello"
s2 <- 'World'
paste(s1, s2)          # "Hello World"(默认空格连接)
paste(s1, s2, sep = "-")  # "Hello-World"
paste0(s1, s2)         # "HelloWorld"(无分隔)

字符串属性

s <- "Hello R"

nchar(s)             # 7 字符数
toupper(s)           # "HELLO R"
tolower(s)           # "hello r"
substring(s, 1, 5)   # "Hello" 截取
substr(s, 7, 7)      # "R"

字符串拼接

# 向量拼接
str_c(c("a", "b"), c("1", "2"))   # 需 stringr 包

# 基础方式
paste(c("a", "b"), collapse = "-")   # "a-b"

# sprintf 格式化
sprintf("姓名: %s, 年龄: %d", "张三", 28)
# "姓名: 张三, 年龄: 28"

查找与替换

s <- "Hello World"

grepl("World", s)          # TRUE 是否包含
regexpr("o", s)            # 第一次出现位置
gregexpr("o", s)           # 所有出现位置

gsub("World", "R", s)      # "Hello R" 替换
sub("l", "L", s)           # "HeLlo World" 只替换第一个

strsplit(s, " ")           # 按空格分割 -> list

stringr 包(推荐)

library(stringr)

str_detect(s, "World")     # TRUE
str_extract(s, "l+")       # "ll"
str_replace(s, "World", "R")
str_split(s, " ")
str_trim("  空格  ")       # "空格" 去空白
str_length(s)              # 11

编码处理

# 中文编码
s <- "中文测试"
Encoding(s)               # "UTF-8"
enc2utf8(s)               # 转 UTF-8
iconv(s, from = "UTF-8", to = "GBK")   # 转 GBK

R 列表

R 列表(List)

列表是 R 中灵活的数据结构,可以容纳不同类型的元素,包括向量、矩阵、数据框甚至其他列表。

创建列表

my_list <- list(
  name = "张三",
  age = 28,
  scores = c(85, 92, 78),
  is_student = TRUE
)

print(my_list)

访问列表元素

# 用 $ 访问(最常用)
my_list$name           # "张三"
my_list$scores         # 85 92 78

# 用 [[]] 取元素本身
my_list[["age"]]       # 28
my_list[[3]]           # 85 92 78(按位置)

# 用 [] 返回子列表(仍是 list)
my_list["name"]        # $name [1] "张三"(是 list)

修改与添加

my_list$age <- 29          # 修改
my_list$city <- "北京"     # 添加
my_list$scores <- NULL     # 删除

# 合并列表
l1 <- list(a = 1)
l2 <- list(b = 2)
combined <- c(l1, l2)      # $a $b

列表的列表(嵌套)

users <- list(
  user1 = list(name = "张三", age = 28),
  user2 = list(name = "李四", age = 30)
)

users$user1$name          # "张三"
users[[2]][["age"]]       # 30

列表操作函数

length(my_list)        # 元素个数
names(my_list)         # 元素名
unlist(my_list)        # 展平为向量(类型需一致)

# lapply:对每个元素应用函数
lapply(list(1:3, 4:6), sum)   # 返回列表

# unlist 结果
unlist(lapply(list(1:3, 4:6), sum))   # 5 15

列表转数据框

# 等长列表转数据框
df <- as.data.frame(list(
  name = c("张三", "李四"),
  age = c(28, 30)
))
print(df)

R 矩阵

R 矩阵(Matrix)

矩阵是二维的同类元素集合,适合数值计算与线性代数操作。

创建矩阵

# matrix(数据, nrow, ncol, byrow)
m <- matrix(1:12, nrow = 3, ncol = 4)
print(m)
#      [,1] [,2] [,3] [,4]
# [1,]    1    4    7   10
# [2,]    2    5    8   11
# [3,]    3    6    9   12

# 按行填充
m2 <- matrix(1:6, nrow = 2, byrow = TRUE)
#      [,1] [,2] [,3]
# [1,]    1    2    3
# [2,]    4    5    6

访问元素

m <- matrix(1:12, nrow = 3)

m[1, 2]        # 第 1 行第 2 列 -> 4
m[1, ]         # 第 1 行全部
m[, 2]         # 第 2 列全部
m[1:2, 3:4]    # 子矩阵
m[3, 2, drop = FALSE]   # 保持矩阵形状

行列名

m <- matrix(1:6, nrow = 2,
            dimnames = list(c("行1", "行2"),
                            c("A", "B", "C")))
m["行1", "B"]      # 2
rownames(m)        # "行1" "行2"
colnames(m)        # "A" "B" "C"

矩阵运算

a <- matrix(1:4, nrow = 2)
b <- matrix(5:8, nrow = 2)

a + b          # 元素加法
a * b          # 元素乘法
a %*% b        # 矩阵乘法
t(a)           # 转置
diag(a)        # 对角线
solve(a)       # 逆矩阵
det(a)         # 行列式
rowSums(a)     # 行和
colSums(a)     # 列和
rowMeans(a)    # 行均值

矩阵与向量

# 结合 rbind/cbind
r1 <- c(1, 2, 3)
r2 <- c(4, 5, 6)
rbind(r1, r2)      # 按行合并
cbind(r1, r2)      # 按列合并

# 矩阵转向量
as.vector(matrix(1:4, nrow = 2))

R 数组

R 数组(Array)

数组是多维数据结构(维度 ≥ 3),矩阵是数组的二维特例。

创建数组

# array(数据, dim = c(维度1, 维度2, 维度3...))
arr <- array(1:24, dim = c(2, 3, 4))
# 2 行 3 列 4 层

# 指定维度名称
arr2 <- array(1:8, dim = c(2, 2, 2),
  dimnames = list(c("r1", "r2"),
                  c("c1", "c2"),
                  c("layer1", "layer2")))

访问数组元素

arr <- array(1:24, dim = c(2, 3, 4))

arr[1, 2, 3]       # 第 1 行第 2 列第 3 层
arr[1, , ]         # 第 1 行所有层
arr[, , 1]         # 第 1 层(得到矩阵)
arr[1, 2, ]        # 一个向量

数组运算

# 与向量/矩阵类似,支持元素级运算
arr + 1
arr * 2

# 维度操作
dim(arr)           # 2 3 4
length(arr)        # 24
apply(arr, 3, sum)        # 每层求和
apply(arr, c(1, 2), sum)  # 按行列聚合

# 转置(置换维度)
aperm(arr, c(3, 2, 1))   # 重排维度

创建规则的数组

# 重复填充
array(0, dim = c(3, 3, 3))          # 全 0
array(rep(1, 8), dim = c(2, 2, 2))  # 全 1

数组的应用场景

1. 多维观测数据(时间 × 变量 × 个体)
2. 图像数据(宽 × 高 × 通道)
3. 模型输出(批量 × 类别)
4. 模拟实验的多维结果

R 因子

R 因子(Factor)

因子用于表示分类变量,在统计建模中至关重要(回归、方差分析都依赖因子)。

创建因子

# 基本因子
gender <- factor(c("男", "女", "男", "女"))
print(gender)
# Levels: 男 女

# 指定水平(顺序)
grade <- factor(c("高", "低", "中"),
                levels = c("低", "中", "高"))
print(grade)
# Levels: 低 中 高

因子属性

levels(gender)       # 所有水平
nlevels(gender)      # 水平数量
table(gender)        # 频数表
# 男 女
#  2  2

有序因子

# 有序:水平有大小关系
temp <- factor(c("低", "高", "中"),
               levels = c("低", "中", "高"),
               ordered = TRUE)

temp[1] < temp[2]    # TRUE(低 < 高)

因子转数值

# 先转字符再转数值,避免得到水平编号
scores <- factor(c("85", "90", "78"))

as.numeric(scores)        # 1 2 3(水平编号,不是原值!)
as.numeric(as.character(scores))   # 85 90 78 ✓

# 或
as.numeric(levels(scores))[scores]

修改因子

# 添加水平
gender <- factor(c("男", "女"))
levels(gender) <- c(levels(gender), "未知")
gender <- c(gender, "未知")   # 添加该水平的观察值

# 重命名水平
levels(gender) <- c("M", "F", "U")

# 删除未使用的水平
gender2 <- droplevels(gender)

因子在建模中的作用

# 回归中因子自动生成哑变量
df <- data.frame(
  y = c(10, 12, 15, 18),
  group = factor(c("A", "A", "B", "B"))
)
lm(y ~ group, data = df)   # groupB 的系数体现差异

R 数据框

R 数据框(Data Frame)

数据框是 R 数据分析最常用的结构,类似 Excel 表格:行是观测,列是变量。

创建数据框

df <- data.frame(
  name = c("张三", "李四", "王五"),
  age = c(28, 30, 25),
  score = c(85, 92, 78),
  stringsAsFactors = FALSE   # 字符串不转因子
)
print(df)

访问数据

# $ 访问列
df$name          # "张三" "李四" "王五"

# 索引
df[1, 2]         # 第 1 行第 2 列 -> 28
df[1, ]          # 第 1 行
df[, "age"]      # age 列
df["name"]       # 返回数据框(单列)

# 常用函数
nrow(df)         # 3 行数
ncol(df)         # 3 列数
dim(df)          # 3 3
names(df)        # 列名
head(df, 2)      # 前 2 行
summary(df)      # 统计摘要

添加与修改列

# 添加列
df$grade <- c("B", "A", "C")
df$pass <- df$score >= 60

# 添加行
new_row <- data.frame(name = "赵六", age = 27,
                      score = 88, grade = "B", pass = TRUE)
df <- rbind(df, new_row)

筛选与排序

# 条件筛选
df[df$age > 26, ]
df[df$score >= 85 & df$age < 30, ]

# subset 函数
subset(df, age > 26, select = c(name, score))

# 排序
df[order(df$score, decreasing = TRUE), ]   # 分数降序
df[order(df$age), ]                        # 年龄升序

dplyr 包(现代数据处理)

library(dplyr)

df %>%
  filter(age > 26) %>%
  select(name, score) %>%
  arrange(desc(score)) %>%
  mutate(level = ifelse(score >= 85, "优秀", "良好")) %>%
  group_by(level) %>%
  summarise(avg_age = mean(age))

R 数据重塑

R 数据重塑

数据分析常需在宽格式与长格式之间转换,以及行列转换。

宽格式 vs 长格式

# 宽格式(每个变量一列)
#   id  q1  q2  q3
# 1  1  85  90  88
# 2  2  78  82  80

# 长格式(每个观测一行,变量名成列)
#   id question score
# 1  1   q1     85
# 2  1   q2     90
# 3  2   q1     78

reshape2 / tidyr 包

library(tidyr)

# 宽转长: pivot_longer
long <- df %>%
  pivot_longer(cols = c(q1, q2, q3),
               names_to = "question",
               values_to = "score")

# 长转宽: pivot_wider
wide <- long %>%
  pivot_wider(names_from = question,
              values_from = score)

reshape() 基础函数

# 宽转长
long <- reshape(df,
  direction = "long",
  varying = c("q1", "q2", "q3"),
  v.names = "score",
  times = c("q1", "q2", "q3"))

行列转置

# t() 转置矩阵/数据框
t(data.frame(a = 1:3, b = 4:6))

# 列转行
library(tidyr)
pivot_longer(df, cols = everything(),
             names_to = "variable", values_to = "value")

合并数据

# 按行合并(追加观测)
rbind(df1, df2)

# 按列合并(添加变量)
cbind(df1, df2)

# 按 key 合并(类似 SQL JOIN)
merge(df1, df2, by = "id")
merge(df1, df2, by = "id", all = TRUE)   # 全外连接
merge(df1, df2, by.x = "id1", by.y = "id2")

聚合(aggregate)

# 分组统计
aggregate(score ~ group, data = df, FUN = mean)
aggregate(cbind(score, age) ~ group, data = df, FUN = sum)

R 包

R 包(Packages)

R 包是可复用的代码集合,CRAN 上有 2 万+ 包可供使用。

安装包

# 从 CRAN 安装
install.packages("ggplot2")
install.packages(c("dplyr", "tidyr", "stringr"))

# 从 GitHub 安装
# install.packages("devtools")
# devtools::install_github("hadley/ggplot2")

# 指定镜像(中国用户)
install.packages("ggplot2",
  repos = "https://mirrors.tuna.tsinghua.edu.cn/CRAN/")

加载与使用

# 加载包
library(ggplot2)     # 推荐
require(dplyr)       # 也可,不强制

# 查看帮助
help(package = "dplyr")
?ggplot

# 已安装包列表
installed.packages()

常用包推荐

数据处理: dplyr, tidyr, data.table
可视化:   ggplot2, plotly, echarts4r
统计建模: stats, lmtest, car
机器学习: caret, randomForest, xgboost
字符串:   stringr
日期:     lubridate
数据导入: readr, readxl, jsonlite, DBI
报告:     rmarkdown, knitr

包版本管理

# 查看版本
packageVersion("ggplot2")     # '3.4.4'
sessionInfo()                 # 完整环境信息

# 更新包
update.packages()

# 卸载
remove.packages("ggplot2")

编写自己的包(简单流程)

# 用 usethis 初始化
# install.packages("usethis")
usethis::create_package("mypackage")
usethis::use_r("hello")

# 目录结构
# mypackage/
# ├── DESCRIPTION    元数据
# ├── NAMESPACE       导出声明
# ├── R/              源码
# └── man/            文档

# 构建与安装
# R CMD build mypackage
# R CMD INSTALL mypackage_0.1.0.tar.gz

R CSV 文件

R CSV 文件读写

CSV 是最常用的数据交换格式,R 提供 read.csv 与 readr 包读取。

读取 CSV

# 基础读取
df <- read.csv("data.csv")
print(head(df))

# 常用参数
df <- read.csv("data.csv",
  header = TRUE,        # 首行是列名
  sep = ",",            # 分隔符
  encoding = "UTF-8",   # 编码
  stringsAsFactors = FALSE,   # 字符串不转因子
  na.strings = c("", "NA")    # 缺失值标记
)

# 指定列类型
df <- read.csv("data.csv", colClasses = c(
  id = "integer",
  name = "character",
  price = "numeric"
))

readr 包(更快更友好)

library(readr)

df <- read_csv("data.csv")
# 自动识别类型,输出解析报告
# 编码问题用 locale
df <- read_csv("data.csv", locale = locale(encoding = "UTF-8"))
df <- read_csv("data.csv", locale = locale(encoding = "GBK"))

写入 CSV

# 基础写入
write.csv(df, "output.csv", row.names = FALSE)
# row.names = FALSE 不写行号

# readr 写入
library(readr)
write_csv(df, "output.csv")

# 追加
write.table(df, "log.csv", append = TRUE,
            sep = ",", col.names = FALSE)

大文件处理

# data.table 高效读取
library(data.table)
dt <- fread("big_data.csv")     # 极快

# 分块读取
con <- file("big.csv", "r")
chunk <- read.csv(con, nrows = 1000)
while (nrow(chunk) > 0) {
  # 处理 chunk
  chunk <- read.csv(con, nrows = 1000)
}
close(con)

常见问题

1. 中文乱码:设置 encoding = "UTF-8" 或 "GBK"
2. 列名带特殊字符:用 check.names = FALSE
3. 分隔符不是逗号:sep 参数(如 "	" 制表符)
4. 数字变字符:检查是不是有逗号/特殊字符

R Excel 文件

R Excel 文件读写

R 通过 readxl、openxlsx、writexl 等包读写 Excel 文件。

读取 Excel

# readxl:只读,无需 Java
library(readxl)

df <- read_excel("data.xlsx")
df <- read_excel("data.xlsx", sheet = 2)          # 按序号
df <- read_excel("data.xlsx", sheet = "数据表")   # 按名称
df <- read_excel("data.xlsx", range = "A1:D10")   # 指定范围

# 列出所有工作表
excel_sheets("data.xlsx")

读取多个工作表

library(readxl)

sheets <- excel_sheets("data.xlsx")
all_data <- lapply(sheets, function(s) {
  read_excel("data.xlsx", sheet = s)
})
names(all_data) <- sheets
# all_data$Sheet1, all_data$Sheet2 ...

写入 Excel

# writexl:轻量,纯 R 实现
library(writexl)
write_xlsx(df, "output.xlsx")

# openxlsx:功能更全(样式、多表)
library(openxlsx)

# 多工作表
list_of_dfs <- list(销售 = df1, 库存 = df2)
write.xlsx(list_of_dfs, "report.xlsx")

# 自定义样式
wb <- createWorkbook()
addWorksheet(wb, "数据")
writeData(wb, "数据", df)
writeDataTable(wb, "数据", df, startCol = 5)
saveWorkbook(wb, "styled.xlsx", overwrite = TRUE)

xlconnect / xlsx 包(需 Java)

# 如需保留公式或复杂格式
# install.packages("xlsx")   # 需要 Java 环境
# library(xlsx)
# df <- read.xlsx("data.xlsx", sheetIndex = 1)
# write.xlsx(df, "out.xlsx")

常见问题

1. 读取中文列名乱码:read_excel 默认处理较好
2. 数值精度:注意 Excel 浮点存储
3. 大文件:openxlsx 比 readxl 慢,选 readxl 读
4. 公式单元格:readxl 返回缓存值

R XML 文件

R XML 文件处理

R 通过 XML 包或 xml2 包读取和解析 XML 数据。

xml2 包(推荐)

# install.packages("xml2")
library(xml2)

# 读取 XML
doc <- read_xml("data.xml")

# 解析字符串
doc <- read_xml("<root><item>1</item></root>")

# 根元素
root <- xml_root(doc)
xml_name(root)    # "root"

查询节点

library(xml2)

# 查找元素
items <- xml_find_all(doc, "//item")
first <- xml_find_first(doc, "//item")

# 取文本
xml_text(items)

# 取属性
xml_attr(items, "id")

# XPath 条件
xml_find_all(doc, "//book[@category='编程']")
xml_find_all(doc, "//book[price > 50]")

XML 包(经典)

library(XML)

# 解析
doc <- xmlParse("data.xml")
root <- xmlRoot(doc)

# 遍历
books <- xpathApply(doc, "//book", function(node) {
  xmlValue(node[["title"]])
})
print(books)

# 转数据框
df <- xmlToDataFrame("data.xml")

创建 XML

library(xml2)

doc <- xml_new_root("bookstore")

book <- xml_add_child(doc, "book")
xml_set_attr(book, "id", "1001")
xml_add_child(book, "title", "R 语言教程")
xml_add_child(book, "price", "59")

# 输出
as.character(doc)
write_xml(doc, "output.xml")

解析网络 XML(RSS)

library(xml2)

# 获取 RSS
rss <- read_xml("https://example.com/feed.xml")
titles <- xml_find_all(rss, "//item/title")
xml_text(titles)

R JSON 文件

R JSON 文件处理

R 通过 jsonlite 包读取、解析和生成 JSON 数据,是 API 交互的标配。

解析 JSON

# install.packages("jsonlite")
library(jsonlite)

# 解析字符串
json <- '{"name": "张三", "age": 28}'
data <- fromJSON(json)
print(data$name)    # "张三"
print(data$age)     # 28

# 解析文件
data <- fromJSON("data.json")

# 解析 URL(API 接口)
api_data <- fromJSON("https://api.example.com/data")

生成 JSON

library(jsonlite)

# 列表转 JSON
toJSON(list(name = "张三", age = 28))

# 数据框转 JSON
df <- data.frame(name = c("张三", "李四"),
                 score = c(85, 92))
toJSON(df)
# [{"name":"张三","score":85},{"name":"李四","score":92}]

# 美化输出
toJSON(df, pretty = TRUE)

# 写入文件
write_json(df, "output.json")
write_json(df, "output.json", pretty = TRUE)

嵌套 JSON

# 复杂 JSON 用 simplifyVector = FALSE
json <- '{"user": {"name": "张三", "tags": ["A", "B"]}}'
data <- fromJSON(json, simplifyVector = FALSE)
data$user$name      # "张三"
data$user$tags[[1]] # "A"

# 嵌套数据框
data <- fromJSON("complex.json")
data$results        # 自动展开为数据框

JSON 与数据框互转

library(jsonlite)

# 数据框 → JSON → 数据框
json <- toJSON(df)
df2 <- fromJSON(json)

# 列表列(每行为嵌套对象)
df$detail <- lapply(1:nrow(df), function(i) {
  list(level = "A", note = paste0("记录", i))
})
toJSON(df)

与 API 交互完整示例

library(jsonlite)
library(httr)

# GET 请求
resp <- GET("https://api.example.com/users",
            query = list(page = 1))
data <- fromJSON(content(resp, "text"))

# POST 请求
resp <- POST("https://api.example.com/login",
             body = list(user = "admin", pwd = "123"),
             encode = "json")
result <- fromJSON(content(resp, "text"))

R MySQL 连接

R MySQL 数据库连接

R 通过 RMySQL、DBI 等包连接 MySQL 数据库进行数据读写。

1. 安装驱动

# Windows/Linux
install.packages("RMySQL")
install.packages("DBI")

# macOS 可能需要配置
# brew install mysql-connector-c
# install.packages("RMySQL", type = "source")

2. 建立连接

library(DBI)
library(RMySQL)

con <- dbConnect(
  MySQL(),
  host = "localhost",     # 服务器地址
  port = 3306,            # 端口
  dbname = "shop",        # 数据库名
  user = "root",          # 用户名
  password = "123456"     # 密码
)

print(con)

3. 查询数据

# 直接查询(返回数据框)
df <- dbGetQuery(con, "SELECT id, name, price FROM products")
print(head(df))

# 参数化查询(防注入)
df <- dbGetQuery(con,
  "SELECT * FROM products WHERE price > ?",
  params = list(50))

4. 写入数据

# 执行非查询语句
dbExecute(con, "INSERT INTO products (name, price) VALUES ('测试', 9.9)")

# 数据框批量写入
new_data <- data.frame(
  name = c("商品A", "商品B"),
  price = c(19.9, 29.9)
)
dbWriteTable(con, "products", new_data, append = TRUE)

5. 事务处理

dbBegin(con)
tryCatch({
  dbExecute(con, "UPDATE account SET balance = balance - 100 WHERE id = 1")
  dbExecute(con, "UPDATE account SET balance = balance + 100 WHERE id = 2")
  dbCommit(con)          # 提交
}, error = function(e) {
  dbRollback(con)        # 回滚
  print(e$message)
})

6. 关闭连接

# 用完必须关闭
dbDisconnect(con)

# 查看所有连接
dbListConnections(MySQL())

常见问题

1. 中文乱码:连接后执行 SET NAMES utf8mb4
   dbExecute(con, "SET NAMES utf8mb4")
2. 时区问题: SET time_zone = '+08:00'
3. 连接超时:适当调大 timeout 参数

R 绘图 - 饼图

R 绘图 - 饼图(Pie Chart)

饼图用于展示各类别占比,R 的基础绘图与 ggplot2 均可实现。

基础饼图

# 基础 pie()
slices <- c(10, 20, 30, 40)
labels <- c("A", "B", "C", "D")

pie(slices, labels = labels,
    main = "类别占比饼图",
    col = c("red", "blue", "green", "yellow"))

带百分比的饼图

slices <- c(10, 20, 30, 40)
labels <- c("A", "B", "C", "D")

pct <- round(slices / sum(slices) * 100)
labels2 <- paste(labels, pct, "%", sep = " ")

pie(slices, labels = labels2,
    col = rainbow(length(slices)),
    main = "带百分比饼图")

3D 饼图(plotrix 包)

# install.packages("plotrix")
library(plotrix)

pie3D(slices,
      labels = labels,
      explode = 0.1,      # 分离
      main = "3D 饼图",
      col = rainbow(length(slices)))

ggplot2 饼图

library(ggplot2)

df <- data.frame(
  category = c("A", "B", "C", "D"),
  value = c(10, 20, 30, 40)
)

ggplot(df, aes(x = "", y = value, fill = category)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y", start = 0) +
  theme_void() +
  labs(title = "ggplot2 饼图")

饼图注意事项

1. 类别过多(>5)时优先用条形图
2. 比例接近时不易比较,用条形图更直观
3. 3D 饼图有视觉误导,慎用
4. 加标签与颜色提高可读性

R 绘图 - 条形图

R 绘图 - 条形图(Bar Chart)

条形图是分类数据最常用的可视化方式。

基础条形图

# 简单向量
counts <- c(12, 25, 18, 30)
names(counts) <- c("A", "B", "C", "D")

barplot(counts,
        main = "基础条形图",
        xlab = "类别",
        ylab = "数量",
        col = "steelblue")

水平条形图

barplot(counts, horiz = TRUE,
        main = "水平条形图",
        xlab = "数量",
        col = "tomato")

分组条形图

# 矩阵数据
data <- matrix(c(10, 15, 20, 12),
               nrow = 2, byrow = TRUE)
colnames(data) <- c("A", "B")
rownames(data) <- c("2025", "2026")

barplot(data,
        beside = TRUE,          # 并排(TRUE)或堆叠(FALSE)
        legend.text = rownames(data),
        col = c("lightblue", "orange"),
        main = "分组条形图",
        ylab = "数值")

ggplot2 条形图

library(ggplot2)

df <- data.frame(
  category = c("A", "B", "C", "D"),
  value = c(12, 25, 18, 30)
)

# 单系列
ggplot(df, aes(x = category, y = value)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  labs(title = "ggplot2 条形图", x = "类别", y = "数量")

# 分组
df2 <- data.frame(
  year = rep(c("2025", "2026"), each = 4),
  category = rep(c("A", "B", "C", "D"), 2),
  value = c(10, 15, 20, 12, 14, 18, 22, 16)
)
ggplot(df2, aes(x = category, y = value, fill = year)) +
  geom_bar(stat = "identity", position = "dodge") +
  theme_minimal()

数值标签

# 基础绘图加标签
bp <- barplot(counts, col = "steelblue", ylim = c(0, 35))
text(bp, counts, labels = counts, pos = 3)

# ggplot2
ggplot(df, aes(x = category, y = value)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  geom_text(aes(label = value), vjust = -0.5)

R 绘图 - 中文支持

R 绘图 - 中文支持

R 绘图默认字体不含中文字符,需要配置字体与编码解决乱码问题。

1. 绘图中文乱码问题

# 问题:plot 中中文显示为方块
plot(1:10, main = "中文标题")   # 可能出现方块

# 解决:指定支持中文的字体

2. Windows 解决方案

# 指定宋体/微软雅黑
windowsFonts(yahei = windowsFont("Microsoft YaHei"))

plot(1:10, main = "中文标题",
     family = "yahei")

# 全局设置
par(family = "yahei")

3. macOS 解决方案

# 用苹方或冬青黑体
par(family = "PingFang SC")

# 或
par(family = "Heiti SC")

4. Linux 解决方案

# 安装中文字体
# sudo apt install fonts-wqy-zenhei

par(family = "WenQuanYi Zen Hei")
# 或
par(family = "Noto Sans CJK SC")

5. showtext 包(通用方案)

# install.packages("showtext")
library(showtext)

# 加载系统字体
font_add("chinese", "C:/Windows/Fonts/msyh.ttc")  # 路径示例
showtext_auto()

# 之后绘图自动支持中文
plot(1:10, main = "中文标题", xlab = "横轴", ylab = "纵轴")

# 从 Google Fonts 加载
# font_add_google("Noto Sans SC")

6. ggplot2 中文

library(ggplot2)
library(showtext)

showtext_auto()

ggplot(data.frame(x = 1:5, y = 1:5), aes(x, y)) +
  geom_point() +
  labs(title = "中文标题", x = "横轴", y = "纵轴") +
  theme(text = element_text(family = "chinese"))

7. 保存图片

# PNG 保存时指定字体
png("plot.png", width = 800, height = 600, res = 96)
par(family = "yahei")   # 或 showtext
plot(1:10, main = "中文标题")
dev.off()

R 绘图 - 函数曲线图

R 绘图 - 函数曲线图

R 的 curve() 函数可以绘制数学函数的图像,是教学与分析的常用工具。

基础函数曲线

# y = x^2
curve(x^2, from = -5, to = 5,
      main = "y = x²", xlab = "x", ylab = "y")

# 指定函数
curve(sin(x), from = 0, to = 2*pi,
      main = "正弦函数", col = "blue")

多条曲线叠加

# 先画第一条
curve(x^2, from = -3, to = 3, col = "red",
      main = "多项式函数", ylim = c(0, 10))

# 叠加更多
curve(x^3, from = -3, to = 3, col = "blue", add = TRUE)
curve(2*x, from = -3, to = 3, col = "green", add = TRUE)

# 图例
legend("top", legend = c("x²", "x³", "2x"),
       col = c("red", "blue", "green"), lty = 1)

正态分布曲线

# 标准正态
curve(dnorm(x), from = -4, to = 4,
      main = "正态分布", ylab = "密度")

# 不同参数
curve(dnorm(x, mean = 0, sd = 1), from = -5, to = 5,
      col = "red", lwd = 2)
curve(dnorm(x, mean = 0, sd = 2), add = TRUE, col = "blue")
curve(dnorm(x, mean = 2, sd = 1), add = TRUE, col = "green")

legend("topright", legend = c("N(0,1)", "N(0,2)", "N(2,1)"),
       col = c("red", "blue", "green"), lty = 1)

分段函数

f <- function(x) {
  ifelse(x < 0, -x, x^2)
}
curve(f(x), from = -3, to = 3, main = "分段函数")

ggplot2 绘制函数

library(ggplot2)

# 生成点
x <- seq(-5, 5, length.out = 200)
df <- data.frame(x = x, y = x^2)

ggplot(df, aes(x, y)) +
  geom_line(color = "red") +
  labs(title = "y = x²", x = "x", y = "y") +
  theme_minimal()

填充区域

curve(x^2, from = -3, to = 3, main = "填充区域")
polygon(c(-3, seq(-3, 3, 0.1), 3),
        c(0, seq(-3, 3, 0.1)^2, 0),
        col = rgb(0, 0, 1, 0.3), border = NA)

R 绘图 - 散点图

R 绘图 - 散点图(Scatter Plot)

散点图用于展示两个连续变量之间的关系,是探索性分析的基础图表。

基础散点图

# 模拟数据
x <- rnorm(100, mean = 50, sd = 10)
y <- 2 * x + rnorm(100, 0, 20)

plot(x, y,
     main = "基础散点图",
     xlab = "X 变量", ylab = "Y 变量",
     col = "steelblue", pch = 16)

绘制回归线

plot(x, y, col = "steelblue", pch = 16,
     main = "带回归线散点图")

# 线性回归线
abline(lm(y ~ x), col = "red", lwd = 2)

# 平滑曲线
lines(lowess(x, y), col = "green", lwd = 2)

按分组着色

group <- factor(rep(c("A", "B"), each = 50))

plot(x, y, col = c("red", "blue")[group], pch = 16,
     main = "分组散点图")
legend("topleft",
       legend = c("组 A", "组 B"),
       col = c("red", "blue"), pch = 16)

气泡图(点大小表示第三维)

size <- runif(100, 1, 10)
plot(x, y, cex = size,    # 点大小按 size
     col = rgb(0, 0.5, 1, 0.5), pch = 16,
     main = "气泡图")

ggplot2 散点图

library(ggplot2)

df <- data.frame(x, y, group)

ggplot(df, aes(x, y)) +
  geom_point(color = "steelblue", alpha = 0.6) +
  geom_smooth(method = "lm", se = TRUE, color = "red") +
  labs(title = "ggplot2 散点图", x = "X", y = "Y") +
  theme_minimal()

# 分组 + 颜色
ggplot(df, aes(x, y, color = group)) +
  geom_point(size = 3, alpha = 0.7) +
  scale_color_manual(values = c("red", "blue")) +
  theme_minimal()

散点图矩阵

# 多变量关系
data(mtcars)
pairs(mtcars[, c("mpg", "hp", "wt", "cyl")],
      main = "散点图矩阵",
      pch = 20, col = "steelblue")

Java 中操作 R

Java 中操作 R

通过 Rserve 或 JRI,Java 程序可以调用 R 的统计计算能力。

方案对比

JRI: 进程内嵌 R(需本地 R,启动快但脆弱)
Rserve: 独立 R 服务(稳定,适合生产,推荐)

1. 启动 Rserve

# 在 R 中安装并启动
install.packages("Rserve")
library(Rserve)
Rserve(args = "--no-save")   # 默认端口 6311

# 或带认证
Rserve(args = "--no-save --RS-auth")
# 配置文件 /etc/Rserv.conf:
# auth required
# plaintext enable

2. Maven 依赖

<dependency>
  <groupId>org.rosuda.REngine</groupId>
  <artifactId>Rserve</artifactId>
  <version>1.8.1</version>
</dependency>

3. Java 连接并执行

import org.rosuda.REngine.Rserve.*;

public class RCallExample {
    public static void main(String[] args) throws Exception {
        // 连接 Rserve
        RConnection c = new RConnection("localhost", 6311);

        // 执行 R 代码
        c.eval("x <- c(1,2,3,4,5)");
        c.eval("y <- mean(x)");

        // 获取结果
        double mean = c.eval("y").asDouble();
        System.out.println("平均值: " + mean);

        // 传递数据给 R
        c.assign("values", new double[]{1.5, 2.5, 3.5});
        double result = c.eval("sum(values)").asDouble();
        System.out.println("和: " + result);

        c.close();
    }
}

4. 返回数据框

// R 返回数据框
REXP result = c.eval("data.frame(name=c('A','B'), score=c(90,80))");
// 按列读取
String[] names = result.asList().at(0).asStrings();
double[] scores = result.asList().at(1).asDoubles();

5. 调用 R 绘图

// 在 R 中生成图片保存到文件
c.eval("png('/tmp/plot.png')");
c.eval("plot(1:10, main='Java 调用的 R 图')");
c.eval("dev.off()");

6. 异常处理与关闭

try (RConnection c = new RConnection()) {
    // 使用连接
} catch (RserveException | REXPMismatchException e) {
    e.printStackTrace();
}
// try-with-resources 自动关闭

7. 常见问题

1. 连接失败:确认 Rserve 已启动、端口开放
2. 认证失败:配置 Rserv.conf 或关闭认证
3. 中文乱码:设置 UTF-8 编码
4. 并发:为每个请求建连接或用连接池

R 语言实例

R 语言综合实例

通过一个"学生成绩分析"实例,串联 R 的读写、统计、可视化全流程。

1. 生成数据

set.seed(42)   # 固定随机种子

students <- data.frame(
  name = paste0("学生", 1:50),
  class = rep(c("一班", "二班"), each = 25),
  math = round(rnorm(50, 75, 10)),
  english = round(rnorm(50, 70, 12)),
  stringsAsFactors = FALSE
)
# 保证分数在 0-100
students$math <- pmax(0, pmin(100, students$math))
students$english <- pmax(0, pmin(100, students$english))

2. 数据概览

head(students)
summary(students)
# 各班人数
table(students$class)
# 成绩分布
hist(students$math, main = "数学成绩分布", col = "skyblue")

3. 统计分析

# 各班平均分
aggregate(cbind(math, english) ~ class,
          data = students, FUN = mean)

# 相关性
cor(students$math, students$english)

# 总体均分
students$total <- students$math + students$english
mean(students$total)
# 最高分
students[which.max(students$total), ]

4. 可视化

library(ggplot2)

# 箱线图对比各班
ggplot(students, aes(x = class, y = math, fill = class)) +
  geom_boxplot() +
  labs(title = "两班数学成绩对比") +
  theme_minimal()

# 散点图看相关
ggplot(students, aes(x = math, y = english, color = class)) +
  geom_point(size = 3) +
  geom_smooth(method = "lm") +
  labs(title = "数学与英语成绩关系") +
  theme_minimal()

5. 导出结果

# 保存清洗后数据
write.csv(students, "students_analysis.csv", row.names = FALSE)

# 保存图表
ggsave("score_boxplot.png", width = 8, height = 6)

6. 完整流程总结

数据生成/读取 → 概览清洗 → 分组统计
→ 相关性分析 → 可视化 → 导出报告

R 语言学习资源

R 语言学习资源与进阶方向

本教程之外,官方文档与社区提供了丰富的 R 学习资源。

官方资源

官网:       r-project.org
文档:       cran.r-project.org/manuals.html
包仓库:     cran.r-project.org
RStudio:    posit.co
R 帮助:     help() / ?函数名 内置文档

经典书籍

入门:
  《R 语言实战》(R in Action)
  《R for Data Science》(R4DS, 免费在线)

进阶:
  《Advanced R》
  《ggplot2: Elegant Graphics for Data Analysis》
  《The Elements of Statistical Learning》

常用扩展方向

数据科学:  dplyr + tidyr + ggplot2 全家桶
机器学习:  caret, tidymodels, xgboost
报告生成:  R Markdown / Quarto
Shiny 应用: 交互式 Web 仪表盘
可视化:    plotly, highcharter, leaflet(地图)
金融分析:  quantmod, PerformanceAnalytics
生物信息:  Bioconductor 生态

学习路径建议

1. 掌握基础语法与数据结构(向量/数据框)
2. 学会 dplyr 数据处理流程
3. 熟练 ggplot2 数据可视化
4. 掌握 R Markdown 报告输出
5. 按需学习建模/机器学习/Shiny
6. 多动手:Kaggle、TidyTuesday 实战

社区与问答

Stack Overflow:  #r 标签
R-bloggers:      全球 R 博客聚合
R Weekly:        每周精选
知乎/公众号:     中文社区(数据分析、统计方向)

实践建议

1. 用真实数据分析练习
2. 参与 TidyTuesday 每周数据可视化
3. 尝试用 Shiny 部署一个仪表盘
4. 阅读高质量包源码(ggplot2 等)
5. 写自己的函数与包,提升工程化能力
第 1 / 30 节