R语言基础

R语言在生物信息学中的应用

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

2026-03-19

课程大纲

本讲内容

  1. 数据科学与R语言
  2. R对象
  3. R向量
  4. R常见数据结构
  1. 运算符与向量运算
  2. R编程
  3. 函数及应用
  4. 取子集

第1部分:数据科学与R语言

1.1 什么是数据科学?

数据科学是利用编程统计专业知识从数据中提取价值的学科

数据科学三要素

  • 🧮 编程:工具(R / Python)
  • 📊 统计:灵魂
  • 🔬 专业:核心(生物医学)

目的不是培养程序员,而是用数据推动学科发展

数据科学流程

  1. 数据导入
  2. 数据规整(清洗)
  3. 数据处理
  4. 可视化
  5. 建模
  6. 可重复性报告

1.2 R是什么?

1992年,新西兰奥克兰大学 Ross IhakaRobert Gentleman 开发了R语言

核心特点

  • 📊 统计计算与图形可视化
  • 💻 跨平台:Windows / Mac / Linux
  • 💰 开源免费(GPL协议)
  • 📦 丰富的包生态系统
  • 👥 活跃的社区支持

R在生物医学中的应用

  • 🧬 RNA-seq差异表达(DESeq2)
  • 🔬 单细胞测序分析(Seurat)
  • 📈 临床数据统计(survival)
  • 🗺️ 基因组注释(GenomicRanges)
  • 📝 可重复研究(R Markdown/Quarto)

1.3 R大神与tidyverse

Hadley Wickham

2019年荣获考普斯总统奖(统计学诺贝尔奖)

  • 创建了 tidyverse 生态系统
  • 彻底改变了现代R编程风格
  • 著有 R for Data Science 等经典书籍
  • 个人主页:https://hadley.nz/

tidyverse:数据科学全家桶

install.packages("tidyverse")
library(tidyverse)

核心包:

  • dplyr — 数据处理
  • ggplot2 — 数据可视化
  • tidyr — 数据整理
  • readr — 数据读取
  • stringr — 字符处理

tidyverse官网:https://www.tidyverse.org/

1.4 安装R和RStudio

安装步骤

① 安装R

② 安装RStudio

RStudio四大面板

┌──────────────┬──────────────┐
│    源代码    │    环境/历史  │
│  (脚本编辑)  │  (变量查看)  │
├──────────────┼──────────────┤
│    控制台    │  文件/图形/  │
│  (命令输入)  │  包/帮助     │
└──────────────┴──────────────┘

1.4 安装R和RStudio

RStudio

1.5 Positron - The Data Science IDE

第2部分:R对象

2.1 一切皆对象

在R中存储的数据称为对象(object),R语言数据处理就是不断创建和操控这些对象

R可以当计算器使用

1 + 1
[1] 2
2 ^ 10
[1] 1024
sqrt(16)
[1] 4

2.1 一切皆对象

查看对象类型

class(3.14)
[1] "numeric"
class("TP53")
[1] "character"
class(TRUE)
[1] "logical"

2.2 对象的创建与赋值

使用赋值操作符 <-= 将数据赋值给变量

# 创建变量(相当于给盒子贴上名字并装入数据)
gene_name <- "TP53"        # 字符型
expression <- 8.5          # 数值型
is_DE <- TRUE              # 逻辑型
sample_count <- 100L       # 整数型

# 查看变量值
gene_name
[1] "TP53"
expression
[1] 8.5

2.3 变量命名规则

✅ 合法的命名

  • 字母、数字、下划线 _、句点 . 组成
  • 第一个字符必须是字母或句点
  • 区分大小写(geneGene
gene_name <- "TP53"      # 推荐
patient.age <- 45        # 可用
x1 <- 100                # 简单

❌ 非法的命名

1gene <- "TP53"    # 数字开头❌
_expr <- 8.5       # 下划线开头❌
my gene <- "TP53"  # 含空格❌

💡 命名最佳实践

# 描述清晰,使用小写+下划线
male_height_cm <- 175   # 最佳
maleHeight <- 175       # 可以
h <- 175                # 避免

2.4 对象属性

x <- c(1.5, 2.3, 8.7, 4.1)

# 类型和长度是最重要的两个属性
typeof(x)       # 内部存储类型
[1] "double"
class(x)        # 对象类型
[1] "numeric"
length(x)       # 元素个数
[1] 4

2.5 属性与赋值

# 属性赋值
names(x) <- c("S1", "S2", "S3", "S4")
attr(x, "unit") <- "FPKM"
attributes(x)
$names
[1] "S1" "S2" "S3" "S4"

$unit
[1] "FPKM"

第3部分:R向量

3.1 向量:R的核心数据结构

向量(vector)是R最基础的数据类型,元素类型统一,用 c() 创建

创建向量

# 数值型向量
expr <- c(8.5, 12.3, 6.7, 15.2, 9.1)

# 字符型向量
genes <- c("TP53", "KRAS", "BRCA1")

# 逻辑型向量
de_flag <- c(TRUE, FALSE, TRUE)

# 单个值也是长度为1的向量
x <- 6
length(x)
[1] 1

生成序列

# 整数序列
1:10
 [1]  1  2  3  4  5  6  7  8  9 10
# 指定步长
seq(0, 1, by = 0.25)
[1] 0.00 0.25 0.50 0.75 1.00
# 重复
rep(c("Tumor", "Normal"), times = 3)
[1] "Tumor"  "Normal" "Tumor"  "Normal" "Tumor"  "Normal"
rep(c("Tumor", "Normal"), each = 3)
[1] "Tumor"  "Tumor"  "Tumor"  "Normal" "Normal" "Normal"

3.2 向量类型详解 - 数值型:integer vs double

x_int <- 42L        # integer(整数,后缀L)
x_dbl <- 42.0       # double(浮点数)

typeof(x_int)
[1] "integer"
typeof(x_dbl)
[1] "double"
is.integer(x_int)
[1] TRUE

3.2 向量类型详解 - 字符串型(String)

gene <- "TP53"      # 双引号或单引号
sample_id <- 'GSM001'
nchar(gene)         # 字符串长度
[1] 4

3.3 因子型向量(factor)

因子是带有层级(Levels)的字符串向量,用于表示分类变量

# 创建因子
stage <- factor(c("I", "II", "III", "II", "IV", "I"))
stage
[1] I   II  III II  IV  I  
Levels: I II III IV
levels(stage)
[1] "I"   "II"  "III" "IV" 
table(stage)
stage
  I  II III  IV 
  2   2   1   1 

3.3 因子型向量(factor)

# 有序因子(如温度等级)
severity <- factor(c("mild", "severe", "moderate", "mild"),
                   levels = c("mild", "moderate", "severe"),
                   ordered = TRUE)
severity
[1] mild     severe   moderate mild    
Levels: mild < moderate < severe
severity[1] < severity[2]
[1] TRUE

3.4 命名向量

# 每个元素可以有名字
expr <- c(TP53 = 8.5, KRAS = 12.3, BRCA1 = 6.7, MYC = 15.2)
expr
 TP53  KRAS BRCA1   MYC 
  8.5  12.3   6.7  15.2 
# 访问命名元素
expr["TP53"]
TP53 
 8.5 
names(expr)
[1] "TP53"  "KRAS"  "BRCA1" "MYC"  

3.5 强制类型转换

向量元素必须是同一类型,若类型不同,R自动转换(强制转换

转换层级规则

character > numeric > logical
double > integer

3.5 强制类型转换

# 混合类型会自动转换
c(1, "USA", TRUE)   # 全部变为字符型
[1] "1"    "USA"  "TRUE"
c(1, TRUE, FALSE)   # 逻辑→数值
[1] 1 1 0

3.5 强制类型转换

# 显式转换
as.numeric("3.14")
[1] 3.14
as.character(100)
[1] "100"
as.logical(0)
[1] FALSE

第4部分:R常见数据结构

4.1 基础数据结构概览

数据结构 维度 元素类型 适用场景
vector 1维 统一 单列数据、序列
matrix 2维 统一 基因表达矩阵
list 任意 混合 分析结果集合
data.frame 2维 混合 临床数据表格

💡 矩阵、列表、数据框都可以看作向量的衍生结构

4.2 矩阵(matrix)

矩阵是二维的向量,所有元素类型相同

# 创建基因表达矩阵
expr_mat <- 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
)

# 行列命名
rownames(expr_mat) <- c("TP53", "KRAS", "BRCA1")
colnames(expr_mat) <- c("S1", "S2", "S3", "S4")
expr_mat
       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

4.2 矩阵(matrix)

dim(expr_mat)     # 维度
[1] 3 4
nrow(expr_mat)    # 行数
[1] 3
ncol(expr_mat)    # 列数
[1] 4

4.3 列表(list)

列表像一列火车,每节车厢可以装不同类型的数据

# 存储分析结果
result <- list(
  gene     = "TP53",
  expr     = c(8.5, 12.3, 6.7, 15.2),
  p_value  = 0.0023,
  is_DE    = TRUE
)

result
$gene
[1] "TP53"

$expr
[1]  8.5 12.3  6.7 15.2

$p_value
[1] 0.0023

$is_DE
[1] TRUE

4.3 列表(list)

# 访问元素
result$gene
[1] "TP53"
result[["p_value"]]
[1] 0.0023
result[[2]]
[1]  8.5 12.3  6.7 15.2

4.4 数据框(data.frame)

数据框 = 等长向量组成的列表,类似Excel表格,生物信息学最常用数据结构

# 患者临床数据
patients <- data.frame(
  id        = c("P001", "P002", "P003", "P004", "P005"),
  age       = c(45, 52, 38, 61, 29),
  gender    = c("M", "F", "F", "M", "F"),
  stage     = c("II", "III", "I", "IV", "II"),
  tp53_expr = c(8.5, 12.3, 6.7, 15.2, 9.1)
)
patients
    id age gender 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

4.5 数据框操作

# 查看结构
str(patients)
'data.frame':   5 obs. of  5 variables:
 $ id       : chr  "P001" "P002" "P003" "P004" ...
 $ age      : num  45 52 38 61 29
 $ gender   : chr  "M" "F" "F" "M" ...
 $ stage    : chr  "II" "III" "I" "IV" ...
 $ tp53_expr: num  8.5 12.3 6.7 15.2 9.1
dim(patients)
[1] 5 5

4.5 数据框操作

# 访问列(三种方式等价)
patients$age
[1] 45 52 38 61 29
patients[["age"]]
[1] 45 52 38 61 29
patients[, "age"]
[1] 45 52 38 61 29

4.5 数据框操作

# 筛选行
patients[patients$age > 50, ]
    id age gender stage tp53_expr
2 P002  52      F   III      12.3
4 P004  61      M    IV      15.2
subset(patients, stage == "III" | stage == "IV")
    id age gender stage tp53_expr
2 P002  52      F   III      12.3
4 P004  61      M    IV      15.2

第5部分:运算符与向量运算

5.1 算术运算符

x <- c(10, 20, 30, 40)
y <- c(2, 4, 5, 8)

x + y     # 加法
x - y     # 减法
x * y     # 乘法
x / y     # 除法
x ^ 2     # 乘方
x %% y    # 取余(模运算)
x %/% y   # 整除

5.2 循环补齐原则

两个向量长度不等时,短向量会循环补齐至长向量的长度

# 标量(长度1)与向量运算
c(1, 2, 3, 4) * 2
[1] 2 4 6 8
# 长度整数倍关系
c(1, 2, 3, 4) + c(10, 20)   # c(10,20)补齐为c(10,20,10,20)
[1] 11 22 13 24

5.2 循环补齐原则

# ⚠️ 非整数倍时R会警告
c(1, 2, 3) + c(10, 20)
[1] 11 22 13

5.3 关系运算符

x <- c(8.5, 12.3, 6.7, 15.2, 9.1)

x > 10        # 大于
x >= 10       # 大于等于
x == 9.1      # 等于(注意是==)
x != 9.1      # 不等于

5.3 关系运算符

x <- c(8.5, 12.3, 6.7, 15.2, 9.1)

# 找出高表达基因的位置
which(x > 10)
[1] 2 4
x[x > 10]
[1] 12.3 15.2

5.4 逻辑运算符

a <- c(TRUE, TRUE, FALSE, FALSE)
b <- c(TRUE, FALSE, TRUE, FALSE)

a & b     # 元素级 AND(两者均TRUE)
a | b     # 元素级 OR(至少一个TRUE)
!a        # 取反

5.4 逻辑运算符

# 实际应用:多条件筛选
x <- c(8.5, 12.3, 6.7, 15.2, 9.1)
x[x > 8 & x < 13]    # 中等表达水平
[1]  8.5 12.3  9.1

5.5 特殊值

R中有四种特殊值,在数据分析中需要特别注意

# Inf:无限大
1 / 0;  -1 / 0
[1] Inf
[1] -Inf
# NaN:非数(Not a Number)
0 / 0;  log(-1)
[1] NaN
[1] NaN

5.5 特殊值

# NA:缺失值(Not Available)
x <- c(8.5, NA, 12.3, NA, 6.7)
is.na(x)
[1] FALSE  TRUE FALSE  TRUE FALSE
mean(x, na.rm = TRUE)   # 忽略NA计算
[1] 9.166667
# NULL:空对象
y <- NULL
is.null(y)
[1] TRUE

5.6 其他运算符

# %in%:判断元素是否在集合中
c("TP53", "BRCA1", "EGFR") %in% c("TP53", "KRAS")
[1]  TRUE FALSE FALSE
# 管道运算符(R 4.1+原生支持)
c(1, 5, 3, 2, 4) |> sort() |> rev()
[1] 5 4 3 2 1
# seq_along:生成与向量等长的序列
genes <- c("TP53", "KRAS", "BRCA1")
seq_along(genes)   # 替代1:length(genes)
[1] 1 2 3

第6部分:R编程

6.1 if 语句

# 根据表达量分类
expr_mean <- 12.5

if (expr_mean > 15) {
  cat("高表达\n")
} else if (expr_mean > 10) {
  cat("中等表达\n")
} else {
  cat("低表达\n")
}
中等表达

6.1 if 语句

# ifelse:向量化条件判断
x <- c(8.5, 12.3, 6.7, 15.2, 9.1)
ifelse(x > 10, "高表达", "低表达")
[1] "低表达" "高表达" "低表达" "高表达" "低表达"

6.2 for 循环

序列(向量)中的元素依次进行处理

# 计算多个基因的标准化值
genes <- c("TP53", "KRAS", "BRCA1")
expr  <- c(8.5, 12.3, 6.7)

for (i in seq_along(genes)) {
  zscore <- (expr[i] - mean(expr)) / sd(expr)
  cat(genes[i], "z-score:", round(zscore, 2), "\n")
}
TP53 z-score: -0.23 
KRAS z-score: 1.1 
BRCA1 z-score: -0.86 

6.2 for 循环

# break:找到第一个高表达基因后退出
for (i in seq_along(expr)) {
  if (expr[i] > 10) {
    cat("第一个高表达基因:", genes[i], "\n")
    break
  }
}
第一个高表达基因: KRAS 

6.3 while 和 repeat 循环

# while循环:满足条件则继续
diff <- 1.0; iter <- 0
while (diff > 0.01) {
  diff <- diff * 0.5
  iter <- iter + 1
}
cat("迭代次数:", iter, "\n")
迭代次数: 7 
# repeat:无条件循环,必须用break退出
x <- 1
repeat {
  x <- x * 2
  if (x >= 16) break
}
x
[1] 16

第7部分:函数及应用

7.1 内置函数

R的强大就在于丰富的内置函数,与数学函数 y = f(x) 概念一致

x <- c(2, 7, 8, 9, 3, 1, 5)

# 汇总函数(返回单个值)
mean(x); median(x); sd(x); var(x)
[1] 5
[1] 5
[1] 3.109126
[1] 9.666667
min(x); max(x); sum(x); length(x)
[1] 1
[1] 9
[1] 35
[1] 7

7.1 内置函数

# 向量化函数(返回等长向量)
sqrt(x)
[1] 1.414214 2.645751 2.828427 3.000000 1.732051 1.000000 2.236068
log2(x)
[1] 1.000000 2.807355 3.000000 3.169925 1.584963 0.000000 2.321928
abs(c(-3, 5, -1))
[1] 3 5 1
round(c(3.14159, 2.71828), digits = 2)
[1] 3.14 2.72

7.2 向量化函数 vs 汇总函数

类型 输入 输出 示例
向量化函数 向量(n个元素) 向量(n个元素) sqrt(), log2()
汇总函数 向量(n个元素) 标量(1个元素) mean(), sum()
其他 向量 不等长向量 unique(), table()

7.2 向量化函数 vs 汇总函数

x <- c(2, 7, 8, 9, 3)
x ^ 2 + 5               # 向量化运算
[1]  9 54 69 86 14
x - mean(x)             # 减去均值
[1] -3.8  1.2  2.2  3.2 -2.8
(x - mean(x)) / sd(x)   # Z-score标准化
[1] -1.2201065  0.3852968  0.7063774  1.0274581 -0.8990258

7.3 自定义函数

减少代码重复,提升编程效率

# 定义Z-score标准化函数
my_std <- function(x) {
  (x - mean(x)) / sd(x)
}

# 对多个向量应用
x <- c(2, 7, 8, 9, 3)
y <- c(1, 5, 7, 8, 9, 3)
my_std(x)
[1] -1.2201065  0.3852968  0.7063774  1.0274581 -0.8990258
my_std(y)
[1] -1.4599928 -0.1622214  0.4866643  0.8111071  1.1355499 -0.8111071

7.3 自定义函数

# 带默认参数的函数
analyze_expr <- function(expr, threshold = 10, log2_transform = FALSE) {
  if (log2_transform) expr <- log2(expr + 1)
  high <- expr[expr > threshold]
  list(n_high = length(high), mean_high = mean(high))
}
analyze_expr(c(8.5, 12.3, 6.7, 15.2, 9.1))
$n_high
[1] 2

$mean_high
[1] 13.75

7.4 使用三方包函数

# 安装并加载包
install.packages("dplyr")
library(dplyr)

# 若多个包有同名函数,用::明确指定
dplyr::select(patients, age, stage)

获取帮助

?mean                    # 查看函数文档
help(package = "dplyr")  # 查看包文档
example(mean)            # 运行示例

第8部分:取子集

8.1 子集选取概述

从对象中提取部分数据,是数据分析的基本操作

操作符 适用对象 说明
[ 全部 返回同类型子集
[[ 列表/数据框 返回单个元素
$ 列表/数据框 名字访问元素

8.2 向量取子集

x <- c(8.5, 12.3, 6.7, 15.2, 9.1)
names(x) <- c("S1", "S2", "S3", "S4", "S5")

# 位置索引(R从1开始!)
x[1];  x[c(1, 3, 5)];  x[2:4]
 S1 
8.5 
 S1  S3  S5 
8.5 6.7 9.1 
  S2   S3   S4 
12.3  6.7 15.2 

8.2 向量取子集

# 逻辑索引
x[x > 10]
  S2   S4 
12.3 15.2 
# 命名索引
x[c("S1", "S3")]
 S1  S3 
8.5 6.7 
# 负索引(排除)
x[-2]
  S1   S3   S4   S5 
 8.5  6.7 15.2  9.1 

8.3 矩阵取子集

# 行列位置
expr_mat[1, ]           # 第1行(TP53)
  S1   S2   S3   S4 
 8.5 12.3  6.7 15.2 
expr_mat[, 1:2]         # 前2列(S1, S2)
       S1   S2
TP53  8.5 12.3
KRAS  5.2  7.8
BRCA1 3.1  4.5
expr_mat["KRAS", "S2"]  # 按名字
[1] 7.8

8.3 矩阵取子集

# 矩阵运算
apply(expr_mat, 1, mean)   # 每行均值(1=行)
  TP53   KRAS  BRCA1 
10.675  7.150  5.925 
apply(expr_mat, 2, mean)   # 每列均值(2=列)
      S1       S2       S3       S4 
5.600000 8.200000 8.000000 9.866667 

8.4 列表与数据框取子集

# 列表取子集:[]返回列表,[[]]返回元素本身
result[1]         # 返回列表
$gene
[1] "TP53"
result[[1]]       # 返回元素本身
[1] "TP53"
result$gene       # 等价于result[["gene"]]
[1] "TP53"

8.4 列表与数据框取子集

# 数据框取子集
patients[1:3, ]                          # 前3行
    id age gender stage tp53_expr
1 P001  45      M    II       8.5
2 P002  52      F   III      12.3
3 P003  38      F     I       6.7
patients[, c("id", "age", "stage")]      # 指定列
    id age stage
1 P001  45    II
2 P002  52   III
3 P003  38     I
4 P004  61    IV
5 P005  29    II
patients[patients$age > 50, ]            # 条件筛选行
    id age gender stage tp53_expr
2 P002  52      F   III      12.3
4 P004  61      M    IV      15.2
patients[patients$stage == "IV", "id"]   # 筛选行+列
[1] "P004"

课程总结

本讲要点回顾

数据结构

  • vector:最基础,元素类型统一
  • matrix:二维向量,同类型
  • list:灵活容器,类型混合
  • data.frame:等长向量列表,最常用

向量类型

  • numeric (double/integer)
  • character, logical, factor
  • 强制转换规则

编程要素

  • 赋值 <-,命名规范
  • 运算符:算术、关系、逻辑
  • 特殊值:NA, NaN, Inf, NULL
  • 循环:for, while, repeat
  • 条件:if/else, ifelse()

函数与取子集

  • 内置函数:向量化 vs 汇总
  • 自定义函数
  • 取子集:[, [[, $

课程作业

使用 R Markdown 生成报告并打印提交

set.seed(学号)
weight <- rnorm(20, mean = 60, sd = 15)
height <- rnorm(20, mean = 170, sd = 20)

任务

  1. 自定义函数,根据方差公式写出方差计算函数,与 var() 对比
  2. 自定义函数,根据身高 height(cm)和体重 weight(kg)计算 BMI \[BMI = \frac{weight}{(height/100)^2}\]
  3. 自定义函数,对向量 x 和阈值 threshold(默认60),计算所有大于阈值元素的均值

参考资料

下节预告

我们将学习

  • 📝 Markdown 基础语法
  • 📊 R Markdown 文档结构
  • ⚙️ 代码块选项与输出控制
  • 🌐 Quarto 现代工作流
  • ♻️ 可重复性研究最佳实践

Questions?

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

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

谢谢!