R语言基础

从入门到生物医学数据分析

王诗翔 副教授
中南大学生物医学信息系

课程介绍

为什么学习R?

生物医学数据分析必备

  • 📊 统计分析 — 临床试验、生存分析
  • 🧬 生物信息 — RNA-seq、基因组学
  • 📈 可视化 — 发表级科研图表
  • 📝 可重复性 — R Markdown/Quarto

R语言优势

  • 💰 开源免费 — 学术界首选
  • 📦 包生态丰富 — 20,000+ CRAN包
  • 🔬 Bioconductor — 生信专用2,000+包
  • 👥 社区活跃 — 全球统计学家支持

本讲目标

你将掌握

技能 应用场景
✅ 数据类型与结构 存储患者信息、基因表达数据
✅ 向量化操作 批量处理基因组数据
✅ 控制流与函数 自动化分析流程
✅ R包管理 安装Bioconductor工具

第1部分:R语言概述

R是什么?

R是用于统计计算图形的编程语言与环境

核心特点

特点 说明 生信应用
开源免费 GPL许可证 学术界广泛使用
跨平台 Win/Mac/Linux 服务器/本地均可运行
交互式 即时反馈 快速探索数据
包生态 20,000+包 Bioconductor生信专用

R在生物医学中的应用

三大核心领域

📊 统计分析

  • 临床试验设计
  • 生存分析 (Survival)
  • 多组学整合

🧬 生物信息

  • RNA-seq (DESeq2)
  • 单细胞测序 (Seurat)
  • 基因组变异分析

📈 数据科学

  • 数据清洗 (tidyverse)
  • 机器学习 (caret)
  • 可重复研究

R vs Python 选择指南

何时选择R?

  • ✅ 统计分析为主的研究
  • ✅ 需要发表级可视化
  • ✅ 生物信息学分析
  • ✅ 与统计学家协作

何时选择Python?

  • ✅ 通用编程和深度学习
  • ✅ 大规模数据处理
  • ✅ 生产环境部署

💡 建议:两者互补!R做统计可视化,Python做深度学习

R环境搭建

1. 安装R

# macOS
brew install r

# Ubuntu
sudo apt-get install r-base

# Windows: https://cran.r-project.org/

2. 安装RStudio

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

RStudio界面

┌─────────────────┬─────────────────┐
│   Source        │    Environment  │
│  (代码编辑器)    │   (变量查看)     │
│                 ├─────────────────┤
│                 │ Files/Plots/    │
│                 │ Packages/Help   │
├─────────────────┴─────────────────┤
│           Console (控制台)         │
│           输入命令,查看输出         │
└───────────────────────────────────┘

第2部分:基础数据类型

五大基本数据类型

类型 说明 示例 生信应用
numeric 数值型 3.14 基因表达量
integer 整数型 42L 读数计数
character 字符型 "TP53" 基因名
logical 逻辑型 TRUE 差异表达标志
complex 复数型 3+4i 傅里叶变换

创建变量与查看类型

# 基因表达数据示例
gene_name <- "TP53"          # 字符型
expression <- 8.5            # 数值型
is_significant <- TRUE       # 逻辑型
sample_count <- 100L         # 整数型

# 查看类型
class(expression)
[1] "numeric"
typeof(sample_count)
[1] "integer"

向量:R的核心数据结构

向量是R中最基本的数据结构,所有元素必须是同一类型

创建向量

# 基因表达值
tp53_expr <- c(8.5, 12.3, 6.7, 15.2, 9.1)
samples <- c("Tumor_1", "Tumor_2", "Normal_1", "Normal_2", "Tumor_3")

# 序列生成
1:10                       # 1到10
 [1]  1  2  3  4  5  6  7  8  9 10
seq(1, 100, by = 10)       # 步长为10
 [1]  1 11 21 31 41 51 61 71 81 91
rep(c("Tumor", "Normal"), each = 3)  # 重复
[1] "Tumor"  "Tumor"  "Tumor"  "Normal" "Normal" "Normal"

向量索引与筛选

# 基因表达数据
tp53 <- c(8.5, 12.3, 6.7, 15.2, 9.1)

# 索引(R从1开始!)
tp53[1]              # 第一个样本
[1] 8.5
tp53[c(1, 3, 5)]     # 多个样本
[1] 8.5 6.7 9.1
tp53[2:4]            # 范围
[1] 12.3  6.7 15.2
# 条件筛选
tp53[tp53 > 10]      # 高表达样本
[1] 12.3 15.2
which(tp53 > 10)     # 返回位置
[1] 2 4

向量化运算:R的灵魂

# 两个基因的表达值
tp53 <- c(8.5, 12.3, 6.7, 15.2)
kras <- c(5.2, 7.8, 9.1, 6.5)

# 逐元素运算
tp53 + kras               # 表达量之和
[1] 13.7 20.1 15.8 21.7
tp53 * 2                  # 标准化
[1] 17.0 24.6 13.4 30.4
tp53 > 10                 # 高表达判断
[1] FALSE  TRUE FALSE  TRUE
# 统计函数
mean(tp53)                # 平均值
[1] 10.675
sd(tp53)                  # 标准差
[1] 3.814337
sum(tp53 > 10)            # 高表达样本数
[1] 2

💡 最佳实践:用向量化代替循环,速度提升10-100倍!

矩阵:二维数据结构

# 创建表达矩阵(基因 × 样本)
expr_matrix <- matrix(
  c(8.5, 12.3, 6.7, 15.2,
    5.2, 7.8, 9.1, 6.5,
    3.1, 4.5, 8.2, 7.9),
  nrow = 3, byrow = TRUE
)

# 命名
dimnames(expr_matrix) <- list(
  c("TP53", "KRAS", "BRCA1"),      # 基因名
  c("S1", "S2", "S3", "S4")         # 样本名
)
expr_matrix
       S1   S2  S3   S4
TP53  8.5 12.3 6.7 15.2
KRAS  5.2  7.8 9.1  6.5
BRCA1 3.1  4.5 8.2  7.9

数据框:最重要的结构

# 患者临床数据
patients <- data.frame(
  patient_id = c("P001", "P002", "P003", "P004", "P005"),
  age = c(45, 52, 38, 61, 29),
  gender = c("M", "F", "F", "M", "F"),
  tumor_stage = c("II", "III", "I", "IV", "II"),
  tp53_expr = c(8.5, 12.3, 6.7, 15.2, 9.1)
)
patients
  patient_id age gender tumor_stage tp53_expr
1       P001  45      M          II       8.5
2       P002  52      F         III      12.3
3       P003  38      F           I       6.7
4       P004  61      M          IV      15.2
5       P005  29      F          II       9.1

数据框操作

访问列

patients$tp53_expr              # $符号访问
[1]  8.5 12.3  6.7 15.2  9.1
patients[["age"]]               # 双括号访问
[1] 45 52 38 61 29
patients[, c("age", "gender")]  # 多列选择
  age gender
1  45      M
2  52      F
3  38      F
4  61      M
5  29      F

筛选行

patients[patients$age > 50, ]           # 老年患者
  patient_id age gender tumor_stage tp53_expr
2       P002  52      F         III      12.3
4       P004  61      M          IV      15.2
patients[patients$tumor_stage == "IV", ] # 晚期患者
  patient_id age gender tumor_stage tp53_expr
4       P004  61      M          IV      15.2
subset(patients, tp53_expr > 10)        # 高表达患者
  patient_id age gender tumor_stage tp53_expr
2       P002  52      F         III      12.3
4       P004  61      M          IV      15.2

数据框常用函数

str(patients)              # 数据结构
'data.frame':   5 obs. of  5 variables:
 $ patient_id : chr  "P001" "P002" "P003" "P004" ...
 $ age        : num  45 52 38 61 29
 $ gender     : chr  "M" "F" "F" "M" ...
 $ tumor_stage: chr  "II" "III" "I" "IV" ...
 $ tp53_expr  : num  8.5 12.3 6.7 15.2 9.1
summary(patients)          # 统计摘要
  patient_id             age        gender          tumor_stage       
 Length:5           Min.   :29   Length:5           Length:5          
 Class :character   1st Qu.:38   Class :character   Class :character  
 Mode  :character   Median :45   Mode  :character   Mode  :character  
                    Mean   :45                                        
                    3rd Qu.:52                                        
                    Max.   :61                                        
   tp53_expr    
 Min.   : 6.70  
 1st Qu.: 8.50  
 Median : 9.10  
 Mean   :10.36  
 3rd Qu.:12.30  
 Max.   :15.20  
head(patients, 3)          # 前3行
  patient_id age gender tumor_stage tp53_expr
1       P001  45      M          II       8.5
2       P002  52      F         III      12.3
3       P003  38      F           I       6.7
dim(patients)              # 行列数
[1] 5 5
nrow(patients)             # 行数
[1] 5
colnames(patients)         # 列名
[1] "patient_id"  "age"         "gender"      "tumor_stage" "tp53_expr"  

列表:灵活的数据容器

# 存储分析结果
analysis_result <- list(
  gene = "TP53",
  expression = c(8.5, 12.3, 6.7, 15.2),
  statistics = list(
    mean = 10.675,
    sd = 3.82,
    p_value = 0.001
  ),
  significant = TRUE
)

# 访问元素
analysis_result$statistics$mean
[1] 10.675
analysis_result[["expression"]]
[1]  8.5 12.3  6.7 15.2

第3部分:控制流与函数

条件语句

# 根据表达量分类
tp53_mean <- mean(tp53_expr)

if (tp53_mean > 15) {
  category <- "高表达"
} else if (tp53_mean > 10) {
  category <- "中表达"
} else {
  category <- "低表达"
}
category
[1] "中表达"

向量化条件:ifelse

# 批量分类多个基因
expression <- c(8.5, 12.3, 6.7, 15.2, 9.1)

# 二分类
high_expr <- ifelse(expression > 10, "高", "低")

# 多分类
grade <- ifelse(expression > 15, "A",
         ifelse(expression > 10, "B", "C"))

循环语句

for循环示例

# 计算每个样本的总表达量
genes <- c("TP53", "KRAS", "BRCA1")
total_expr <- 0

for (gene in genes) {
  expr <- sample(5:15, 1)
  total_expr <- total_expr + expr
  print(paste(gene, ":", expr))
}
[1] "TP53 : 12"
[1] "KRAS : 13"
[1] "BRCA1 : 10"

while循环

# 迭代直到收敛
diff <- 1.0
iter <- 0
while (diff > 0.01) {
  diff <- diff * 0.5
  iter <- iter + 1
}

循环控制

# break: 找到第一个高表达基因
for (i in 1:length(expression)) {
  if (expression[i] > 12) {
    print(paste("找到高表达基因,位置:", i))
    break
  }
}
[1] "找到高表达基因,位置: 2"
# next: 跳过缺失值
for (val in c(8.5, NA, 12.3, NA, 6.7)) {
  if (is.na(val)) next
  print(val)
}
[1] 8.5
[1] 12.3
[1] 6.7

自定义函数

计算BMI

calculate_bmi <- function(weight_kg, height_m) {
  bmi <- weight_kg / (height_m ^ 2)
  
  category <- ifelse(bmi < 18.5, "偏瘦",
              ifelse(bmi < 25, "正常",
              ifelse(bmi < 30, "超重", "肥胖")))
  
  return(list(
    bmi = round(bmi, 2),
    category = category
  ))
}

calculate_bmi(70, 1.75)
$bmi
[1] 22.86

$category
[1] "正常"

生信专用函数示例

计算Fold Change

calculate_fc <- function(tumor, normal, log2 = TRUE) {
  # 计算均值
  mean_tumor <- mean(tumor)
  mean_normal <- mean(normal)
  
  # 计算Fold Change
  fc <- mean_tumor / mean_normal
  
  if (log2) {
    fc <- log2(fc)
  }
  
  return(fc)
}

# 使用示例
tumor_expr <- c(12.3, 15.2, 18.5, 14.1)
normal_expr <- c(6.7, 7.8, 8.2, 7.5)
calculate_fc(tumor_expr, normal_expr)
[1] 0.9928164

函数参数与默认值

# 差异表达分析函数
analyze_de <- function(expression, 
                       group,
                       method = "t-test",
                       alpha = 0.05) {
  # 分组
  group1 <- expression[group == "Tumor"]
  group2 <- expression[group == "Normal"]
  
  # t检验
  result <- t.test(group1, group2)
  
  list(
    p_value = result$p.value,
    significant = result$p.value < alpha,
    method = method
  )
}

# 使用
expr <- c(12.3, 15.2, 18.5, 6.7, 7.8, 8.2)
group <- c("Tumor", "Tumor", "Tumor", "Normal", "Normal", "Normal")
analyze_de(expr, group)
$p_value
[1] 0.0423099

$significant
[1] TRUE

$method
[1] "t-test"

第4部分:R包生态

R包生态概览

两大核心仓库

仓库 定位 包数量 生信代表
CRAN 综合R包 20,000+ ggplot2, dplyr
Bioconductor 生物信息 2,000+ DESeq2, Seurat

安装R包

从CRAN安装

install.packages("ggplot2")
install.packages(c("dplyr", "tidyr", "readr"))

从Bioconductor安装

if (!require("BiocManager"))
    install.packages("BiocManager")

BiocManager::install("DESeq2")
BiocManager::install(c("GenomicRanges", "Biostrings"))

加载与使用

# 加载包
library(ggplot2)
require(dplyr)

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

# 列出已加载包
search()

必学生物医学R包

tidyverse生态(数据科学)

功能 生信应用
dplyr 数据处理 筛选基因、分组统计
ggplot2 可视化 火山图、热图
readr 数据读取 读取表达矩阵
tidyr 数据整理 长宽格式转换

Bioconductor生态(生物信息)

功能 应用场景
DESeq2 RNA-seq分析 差异表达
Seurat 单细胞分析 细胞聚类
GenomicRanges 基因组区间 注释分析

第5部分:综合案例

案例:TP53基因表达分析

背景

分析5个肿瘤样本和5个正常样本的TP53基因表达数据

# 创建数据
samples <- c(paste0("Tumor_", 1:5), paste0("Normal_", 1:5))
groups <- c(rep("Tumor", 5), rep("Normal", 5))
tp53_expr <- c(12.5, 15.2, 8.7, 18.3, 11.9,
               6.2, 7.5, 5.8, 8.1, 6.9)

# 创建数据框
data <- data.frame(
  sample = samples,
  group = groups,
  expression = tp53_expr
)

数据分析流程

# 1. 查看数据
head(data)
    sample  group expression
1  Tumor_1  Tumor       12.5
2  Tumor_2  Tumor       15.2
3  Tumor_3  Tumor        8.7
4  Tumor_4  Tumor       18.3
5  Tumor_5  Tumor       11.9
6 Normal_1 Normal        6.2
str(data)
'data.frame':   10 obs. of  3 variables:
 $ sample    : chr  "Tumor_1" "Tumor_2" "Tumor_3" "Tumor_4" ...
 $ group     : chr  "Tumor" "Tumor" "Tumor" "Tumor" ...
 $ expression: num  12.5 15.2 8.7 18.3 11.9 6.2 7.5 5.8 8.1 6.9
# 2. 分组统计
aggregate(expression ~ group, data = data, FUN = mean)
   group expression
1 Normal       6.90
2  Tumor      13.32
# 3. 差异分析
tumor <- data$expression[data$group == "Tumor"]
normal <- data$expression[data$group == "Normal"]
result <- t.test(tumor, normal)
result$p.value
[1] 0.01458753

结果解读

统计结果

指标 数值 解释
肿瘤组均值 13.32 高表达
正常组均值 6.90 低表达
Fold Change 1.93 上调近2倍
p-value < 0.05 显著差异

生物学意义

TP53在肿瘤组中显著上调,提示可能参与肿瘤发生发展

本讲要点

核心概念

  • R是统计计算与图形语言
  • 五大类型:numeric, integer, character, logical, complex
  • 核心结构:vector, matrix, data.frame, list
  • 向量化操作是R的灵魂

生信技能

  • 数据框操作:df$gene, df[condition, ]
  • 统计分析:t.test(), mean(), cor()
  • 函数编写:自动化分析流程
  • 包管理:BiocManager::install()

练习作业

基础练习

  1. 创建一个包含10个患者信息的数据框(ID、年龄、性别、分期、生存时间)
  2. 计算不同分期的平均年龄
  3. 筛选出III-IV期患者

编程练习

  1. 编写函数计算基因表达的标准化值(Z-score)
  2. 使用向量化操作计算1000个基因的平均表达量
  3. 比较向量化 vs 循环的性能差异

思考

  • 为什么R的向量从1开始索引?(对比Python的0索引)
  • 在什么情况下需要使用list而不是data.frame?

下节预告

我们将学习

  • Markdown基础语法
  • R Markdown文档结构
  • 代码块与输出控制
  • Quarto现代工作流
  • 生信报告自动化

Questions?

王诗翔 副教授
中南大学生物医学信息系

📧 wangshx@csu.edu.cn
🐙 https://github.com/WangLabCSU

谢谢!