R 是一门为统计计算与图形而生的开源语言,也是数据科学领域使用最广的工具之一。它由统计学家为数据分析而设计,向量、表格、模型这些概念直接长在语法里,几十年积累下来的扩展包几乎覆盖了从数据清洗到论文排版的每一个环节。2026 年,R 4.6 系列发布,编辑器生态也迎来了 Positron 转正等新变化。这篇文章用科普的方式,把 R 从“它是什么”一路讲到“怎样才能算精通”。

为什么 2026 年还值得花时间学 R

在通用编程语言动辄讨论框架更替的今天,R 的节奏显得很慢,但它在自己的主场几乎没有对手。

  • 统计方法的首发地:大量新的统计方法、检验和模型,第一份可运行的实现往往就出现在 R 的包里,而不是先有商业软件版本。做实证研究、写论文的人,很多方法只能在这里找到。
  • 结构化数据处理的表达力:向量化运算让一行代码替代其他语言里的多层循环,表格数据的筛选、分组、汇总写出来接近自然语言,改起来也快。
  • 可视化能力是护城河:图形语法这套思路让“画一张图”变成“描述数据与图形元素的映射关系”,同一套代码换几行就能从散点图变成分面图、热力图。
  • 学术与行业的双重刚需:医学、生物信息、生态、经济、社会科学、公共卫生、量化金融,这些领域内部的代码、课程、合作者大量使用 R,学会它等于接入一个成熟的协作网络。
  • 沉淀成本低、长期稳定:R 的语法和核心函数几十年保持向后兼容,十年前的脚本今天基本还能跑。这一点对需要复现旧研究的人来说价值极高。

要客观一点的是,R 不是“什么都能做”的语言。它不适合写大型通用后端、不适合进移动端,做深度学习也不如 Python 顺手。把它当作「统计分析与数据可视化的专用工具」,期望值就对了。

R 到底是什么:一门为数据而生的语言

身世与设计哲学

R 诞生于 1993 年,由新西兰奥克兰大学的 Ross Ihaka 和 Robert Gentleman 开发,名字取自两人名字的首字母,也是对它所效仿的贝尔实验室 S 语言的一种玩笑式致敬。1997 年成立 R 核心团队,2000 年发布 1.0.0,此后由全球志愿者共同维护,如今由 R Foundation 负责治理。

它的设计哲学可以概括成几句:

  • 面向数据分析,而不是面向系统开发。默认就有缺失值 NA、有向量、有数据框,不需要额外库。
  • 一切皆向量。多数运算天然按元素并行,写循环往往是多余的。
  • 交互式优先。控制台里一行一行试出来的结果,可以直接固化成脚本。
  • 函数式倾向。函数是“一等公民”,可以作为参数传递、可以返回,配合 apply 家族能写出很紧凑的代码。

R 和 Python 到底该选谁

这是个被问了无数遍的问题,但真实的答案通常是“两个都装”。

  • 统计分析、假设检验、学术绘图、论文报告:首选 R。它的统计函数更全、更贴近教材表述,绘图系统也更擅长出版级图形。
  • 机器学习工程、深度学习、Web 后端、数据管道部署:首选 Python。生态在生产化、部署和工程化上更成熟。
  • 日常可做的折中:用 R 做探索、建模与出图,用 Python 做训练与服务化;两个语言之间通过 reticulate 互相调用已经相当顺畅。

一个务实的判断标准是看你身边的环境:导师、同事、合作者用什么,你就先用什么,能交流的代码才有生命力。

2026 年版本地图:该装哪个 R

版本号与发布节奏

R 的版本号是「主版本.次版本.修订号」。主版本几乎不动,真正变化的是第二位。它的发布节奏相当规律:每年 4 月左右发布当年的 .0 大版本,随后的几个月里发布 .1、.2 修订版修 bug,次年 4 月再进入下一个大版本。这些修订版之间是二进制兼容的,升级时旧脚本基本不用改。

各版本线现状

截至 2026 年,几条版本线的状态如下:

版本代号发布日期定位
4.6.1Happy Hop2026-06-24当前稳定版,新项目首选
4.6.0Because it was There2026-04-244.6 线的首个大版本
4.5.x—2025 年上一代稳定线,仍可用

几个实用结论:

  • 新装就用 4.6.1。它修正了 4.6.0 早期暴露的问题,是当下最省心的选择。
  • 不必追着每个修订版升级。修 bug 的版本对日常分析影响有限,除非你正被某个具体问题困扰。
  • 升级前先备份。新的大版本偶尔会让某些依赖编译的包暂时装不上,等一两周再升级,或者准备好回退方案更稳妥。
  • 想查权威的版本与发布记录,看 R 官方项目主页 的 News 一栏,或者 CRAN 的历史版本目录。

R 4.6 带来了什么

4.6.0 是一次“看不出界面变化、但底子变了”的更新。对普通使用者真正有意义的改动主要有这几处:

  • wilcox.test() 更完善。在处理存在并列值(ties)的数据时,现在可以做精确的条件推断,也能选用带修正项的渐近 p 值。医学、社科数据里评分量表、住院天数这类整数数据很容易出现并列值,这个改进很实用。
  • 新增 free1way()。stats 包里多了一个分布无关的分层多样本推断入口,配套还有功效计算与随机模拟函数。它是补充工具,不是方差分析的替代品。
  • 广义线性模型诊断更严谨。influence.glm() 等影响度量改用皮尔逊残差,weighted.residuals() 对 glm 对象返回加权工作残差,想要精细诊断的人会受用。
  • 基础函数的小升级。新增了 %notin% 运算符、list.files() 增加了字面量匹配参数 fixed、substring() 的终止位置可以传 NULL 表示一直到结尾。
  • 默认 C 标准改为 C++20。这一条主要影响自己编译含 C/C++ 代码的包的人,普通用户感知不到。

环境搭建:从零把 R 跑起来

第一步:安装 R 本体

R 本身只是一个运行时和命令行环境,先装它,再装编辑器,顺序不能反。官网在 r-project.org,点 Download 后选择就近的 CRAN 镜像即可。

Windows 用户下载 .exe 安装包,一路下一步即可;macOS 用户下载 .pkg,或者用 Homebrew 执行 brew install --cask r;Linux 用户直接用发行版包管理器。装完后在终端里验证一下:

R --version

第二步:选一款编辑器

装完 R 之后你会得到一个朴素的控制台,真正顺手的开发还需要一个集成环境。2026 年的主流选择有三类:

  • RStudio Desktop:历史最久、资料最多的 R 专用环境。四宫格布局(脚本、控制台、环境变量、图形与帮助)已经成为很多人的肌肉记忆,免费开源。最新版本延续 2026.x 系列,内置了 AI 助手 Posit Assistant,支持代码生成、解释与调试。
  • Positron:Posit 公司(原 RStudio 公司)推出的新一代数据科学编辑器,基于 VS Code 内核构建,对 R 和 Python 一视同仁。2025 年年中正式转正,到 2026 年已保持按月稳定迭代。它把变量面板、数据浏览器、绘图、帮助文档统一收纳到侧边,R 进程独立运行,崩了也不会带走整个界面。免费下载地址是 positron.posit.co。
  • VS Code + R 扩展:适合已经重度使用 VS Code 的人,配置成本略高,但能和其它语言的工作流统一。

选择建议:完全新手用 RStudio Desktop,能少踩很多坑;同时会 R 和 Python、或者想一套编辑器通吃的人,可以试试 Positron。

第三步:Windows 用户的 Rtools

这一步容易被忽略,但迟早会撞上。R 本身只是一个解释器,当某个包内部含 C、C++ 或 Fortran 源码时,R 需要调用外部的编译器把它编译成动态库。Linux 和 macOS 系统通常自带工具链,Windows 没有,于是就有了 Rtools。

判断标准很简单:装纯 R 包不需要 Rtools,装含原生代码的包(data.table、Rcpp、stringi 这类)就需要。从 GitHub 装开发版包时,几乎必然触发编译。

不装或装错版本的典型症状是安装日志末尾出现编译失败,往前翻能看到找不到编译器的提示。有一点必须记住:Rtools 的版本号要和 R 的主次版本严格对应,比如 R 4.5 配 Rtools45,装错版本会报底层符号找不到的错误,很难排查。安装包在 CRAN 的 Rtools 页面 下载,装完后可在 R 里执行下面这行确认编译器是否已被找到:

Sys.which("make")

只要返回值不是空字符串,就说明配置成功。

国内镜像与基础配置

从国外源下载包在国内可能很慢,第一件事是把镜像换成国内的。写进 ~/.Rprofile 可以持久生效:

# 设置清华大学镜像
options(repos = c(CRAN = "https://mirrors.tuna.tsinghua.edu.cn/CRAN/"))

# 中文环境下的编码设置,避免读文件乱码
options(encoding = "UTF-8")

装包、查包、更新包的基本操作:

install.packages("tidyverse")   # 安装
library(tidyverse)              # 载入
update.packages(ask = FALSE)    # 批量更新已安装的包
packageVersion("dplyr")         # 查看某个包的版本

基础语法:数据结构是一切的地基

向量与向量化运算

向量是 R 里最基本的数据结构,也是理解 R 思维方式的关键。它的特别之处在于:大部分运算默认就是逐元素进行的,不需要你写循环。

x <- c(3, 7, 2, 9, 4)          # 用 c() 构造向量
mean(x)                        # 求平均值
x * 2                          # 每个元素都乘 2
x[x > 4]                       # 逻辑索引,挑出大于 4 的元素
sum(x) / length(x)             # 手算平均值,结果和 mean() 一致

向量运算还有一个容易被忽略的规则叫“循环补齐”:长度不同的向量做运算时,短的会自动重复。

c(1, 2, 3, 4) + c(10, 20)      # 结果是 11 22 13 24

因子、矩阵与数组

  • 因子(factor) 用来表示分类变量,是统计建模里非常重要的类型。有序因子还带有大小关系。
  • 矩阵(matrix) 是二维的同类型数据,常用于线性代数运算。
  • 数组(array) 是矩阵在更多维度上的推广。
# 有序因子:等级有先后
grade <- factor(
  c("低", "高", "中", "低"),
  levels = c("低", "中", "高"),
  ordered = TRUE
)
grade

# 矩阵:按行填充
m <- matrix(1:6, nrow = 2, byrow = TRUE)
m
t(m) %*% m      # 转置相乘

数据框与 tibble

数据框(data.frame)是 R 处理表格数据的核心结构,可以理解为“若干等长向量拼成的一张大表”。tidyverse 生态里的 tibble 是它的现代化版本,打印更克制、不会莫名其妙把字符串转成因子。

df <- data.frame(
  name = c("张三", "李四", "王五"),
  age  = c(28, 35, 42),
  city = c("宜昌", "武汉", "重庆")
)

str(df)                 # 查看结构
df$age                  # 取一列
df[df$age > 30, ]       # 按条件取行

library(tibble)
tb <- tibble(x = 1:3, y = c("a", "b", "c"))
print(tb)

列表

列表(list)最灵活,什么都能装,是 R 里表示“复杂对象”的通用容器。模型拟合的结果、函数的多个返回值,都是列表。

person <- list(
  name   = "张三",
  age    = 28,
  scores = c(88, 92, 79)
)

person$scores        # 用 $ 取元素
person[["name"]]     # 用双方括号取元素,结果会拆包
names(person)        # 查看所有元素名

数据操作的核心:tidyverse 与管道

管道是什么

写数据分析时,我们常常需要对同一份数据连续做七八个操作。传统写法要么层层嵌套括号,要么创建一堆临时变量,都不好读。管道运算符 |> 解决的正是这个问题:把上一步的结果,作为下一步的第一个参数传进去。它从 R 4.1 起成为语言内置能力,老一点的写法是 magrittr 包提供的 %>%,两者含义相同。

# 传统嵌套写法,得从里往外读
summarise(group_by(filter(sales, amount > 140), region), total = sum(amount))

# 管道写法,从上往下读,逻辑一目了然
sales |>
  filter(amount > 140) |>
  group_by(region) |>
  summarise(total = sum(amount))

dplyr 的五个动词

dplyr 把数据操作归纳成几个基本动作,绝大多数复杂变换都能拆成它们的组合:

  • filter():按条件筛行。
  • select():按名字选列,或排除某几列。
  • arrange():排序。
  • mutate():新增或修改列。
  • summarise():汇总成统计量。

配合 group_by() 分组,一个完整的数据清洗流程写出来很像一段说明文字:

library(dplyr)
library(tibble)

sales <- tibble(
  region = c("华北", "华东", "华南", "华东", "华北", "华南"),
  month  = c("1月", "1月", "1月", "2月", "2月", "2月"),
  amount = c(120, 200, 150, 180, 130, 210)
)

result <- sales |>
  filter(amount > 140) |>            # 只保留金额大于 140 的记录
  mutate(amount_wan = amount / 100) |>  # 新增一列,换成“万元”口径
  group_by(region) |>                # 按地区分组
  summarise(
    total    = sum(amount),
    avg      = mean(amount),
    n        = n(),
    .groups  = "drop"
  ) |>
  arrange(desc(total))               # 按总额降序

print(result)

宽长表转换

同一份数据,有时需要“宽表”形态(一行一个对象、多列变量),有时需要“长表”形态(一行一个观测)。tidyr 里的 pivot_longer() 和 pivot_wider() 就是在这两种形态之间来回转换的工具,作图前几乎都会用到。

library(tidyr)

wide <- tibble(id = 1:2, t1 = c(5, 6), t2 = c(7, 8))

long <- wide |>
  pivot_longer(cols = c(t1, t2), names_to = "time", values_to = "value")

long

数据可视化:ggplot2 的图形语法

图层的思维

ggplot2 的核心理念是“图形语法”:一张图由若干图层叠加而成,每个图层声明「用哪些数据、把哪个变量映射到哪个视觉通道(x 轴、y 轴、颜色、大小)、用什么几何对象去画」。理解这条思路之后,画新图就不再需要背参数,而是去描述映射关系。

基本骨架长这样:

  • ggplot(data, aes(...)) 声明数据与映射;
  • geom_*() 决定画什么形状(点、线、柱、箱线);
  • facet_*() 决定如何分面;
  • labs()、theme_*() 负责标题、标签与外观。

一个完整的例子

library(ggplot2)

ggplot(data = iris,
       aes(x = Sepal.Length, y = Petal.Length, color = Species)) +
  geom_point(size = 2, alpha = 0.8) +          # 散点层
  geom_smooth(method = "lm", se = FALSE) +     # 每组的线性趋势线
  labs(
    title = "鸢尾花萼片长度与花瓣长度的关系",
    x     = "萼片长度",
    y     = "花瓣长度",
    color = "品种"
  ) +
  theme_minimal()

值得收藏的扩展

围绕 ggplot2 已经长出一整个生态:patchwork 做多图拼接,ggpubr 面向论文排版,plotly 把静态图变成可交互图,gganimate 让图动起来,ggrepel 解决标签重叠。遇到“这图能不能这样画”的念头时,先去搜一圈扩展包,通常早有人做过了。

统计建模:R 的老本行

线性模型与回归

R 的公式语法 y ~ x1 + x2 是整个建模体系的基础,几乎所有模型函数都接受这套写法。下面用内置数据集 mtcars 拟合一个解释汽车油耗的线性模型:

fit <- lm(mpg ~ wt + hp, data = mtcars)

summary(fit)      # 系数、标准误、p 值、R 方一应俱全
confint(fit)      # 系数的置信区间
coef(fit)         # 只看系数
resid(fit)        # 提取残差

这套面向对象的接口设计得很统一:换一个模型,只需要换函数名,summary()、predict()、plot() 这些方法大多能直接复用。

# 逻辑回归:预测 am 是否自动挡
logit <- glm(am ~ wt + hp, data = mtcars, family = binomial)
summary(logit)

假设检验

常见的检验在 R 里都是一行调用,参数清晰、结果完整:

# 单样本 t 检验
t.test(mtcars$mpg, mu = 20)

# 两样本 t 检验,用公式语法指定分组
t.test(extra ~ group, data = sleep)

# 卡方独立性检验
chisq.test(table(mtcars$cyl, mtcars$am))

# 相关分析
cor.test(mtcars$mpg, mtcars$wt)

tidymodels:现代机器学习工作流

如果说早期的 caret 是“能跑就行”,那么 tidyverse 风格组织的 tidymodels 就是把建模变成了一条可追溯、可复现的流水线。它的思路是先把流程搭好,再往里插模型,于是换算法不需要重写预处理。

library(tidymodels)

set.seed(42)

# 1. 划分数据
split <- initial_split(mtcars, prop = 0.8)
train <- training(split)
test  <- testing(split)

# 2. 定义预处理配方
rec <- recipe(mpg ~ wt + hp + cyl, data = train) |>
  step_normalize(all_numeric_predictors())

# 3. 指定模型与工作流
model <- linear_reg() |> set_engine("lm")
wf    <- workflow() |> add_recipe(rec) |> add_model(model)

# 4. 交叉验证 + 重新拟合 + 评估
folds  <- vfold_cv(train, v = 5)
cv_res <- fit_resamples(wf, resamples = folds)
collect_metrics(cv_res)

这段代码的价值不在于它算出了什么,而在于它的结构:数据划分、预处理、模型、验证被明确分开,明天想把线性回归换成随机森林,改一行 model 的定义就够了。

编程能力进阶:函数、循环与面向对象

函数与作用域

R 的函数有两个特点:一是函数是普通对象,可以赋值、可以当参数传;二是默认参数可以引用其它参数。写自己的函数时,保持单一职责,比写得短更重要。

# 计算变异系数:标准差除以均值
cv <- function(x, na.rm = TRUE) {
  stopifnot(is.numeric(x))
  sd(x, na.rm = na.rm) / mean(x, na.rm = na.rm) * 100
}

cv(c(10, 12, 11, 13, 9))
cv(c(10, NA, 11, 13, 9))

用 apply 家族替代循环

R 里能用向量化就别用循环,退一步也优先用 apply 家族。tidyverse 生态里的 purrr 把这类操作统一成了 map_* 系列,返回类型写在函数名里,读起来更明确。

nums <- list(a = 1:5, b = 6:10, c = 11:15)

lapply(nums, mean)      # 基础写法,返回列表
sapply(nums, mean)      # 尝试简化结果,返回向量

library(purrr)
map_dbl(nums, mean)     # 明确规定返回 double 向量,最不容易出错
map(nums, mean)         # 返回列表

什么时候还是得写循环

不是所有循环都该被消灭。当迭代之间互相依赖、或者需要逐行读写大文件时,老老实实写循环反而更清楚。

vals <- c(3, 8, 1, 6)

result <- numeric(length(vals))
for (i in seq_along(vals)) {
  result[i] <- vals[i] ^ 2
}
result

这里用 seq_along(vals) 而不是 1:length(vals),是因为当向量长度为 0 时,后者会生成 c(1, 0) 两个索引,是个经典陷阱。

面向对象:够用就好

R 有 S3、S4、R6 三套面向对象系统,新手不必全学。理解 S3 就够应付绝大多数场景,它的思路是「给一个普通列表打上类别标签,然后为这个类别写专属方法」。

new_account <- function(balance) {
  structure(list(balance = balance), class = "account")
}

deposit <- function(x, amount) UseMethod("deposit")

deposit.account <- function(x, amount) {
  x$balance <- x$balance + amount
  x
}

acc <- new_account(100)
acc <- deposit(acc, 50)
print(acc$balance)

可重复研究:让报告自动生成

数据分析最尴尬的场面是:图表已经贴进文档,数据一改,全部作废。解决它的工具叫 Quarto,一个把代码、文字和图表合成一份文档的出版系统。它是 R Markdown 生态的集大成者,由 Posit 开发,原生支持 R、Python、Julia 等多种语言,同一份源文件可以输出 HTML、PDF、Word、幻灯片甚至整站。

它的核心思想是:文档里嵌代码块,渲染时才真正执行,结果自动填入文中。报告里的每个数字都与数据同步。

Quarto 是独立的命令行工具,通常随 RStudio 自动安装。一个最小文档的样子是:

# 把 .qmd 文件渲染成网页
quarto render report.qmd --to html

# 也可以直接渲染成 Word 交给不写代码的同事
quarto render report.qmd --to docx

# 检查 Quarto 环境是否完整
quarto check

对写论文、写周报、做实验记录的人来说,这套东西的回报率极高:一次写好模板,之后每次只要更新数据、重新渲染,前言、方法、图表、参考文献全部自动重排。

生态全景:一张地图看懂 R 的版图

R 的能力几乎都来自包。按用途分,下面这些是绕不开的名字:

领域代表包说明
数据处理dplyr、tidyr、data.table前两个是 tidyverse 主力,data.table 以极致的速度著称
数据导入readr、readxl、haven、DBI文本、Excel、SPSS/Stata 文件、数据库连接
可视化ggplot2、patchwork、plotly出版级静态图到交互式网页图
建模stats、tidymodels、lme4、survival基础统计、机器学习流水线、混合效应、生存分析
时间序列forecast、tsibble、fable预测与序列建模
报告出版Quarto、knitr、rmarkdown、flextable可复现文档与表格排版
交互应用shiny、flexdashboard用 R 直接做网页应用与仪表盘
高性能Rcpp、parallel、future把热点代码交给 C++,把任务分给多核
生物信息Bioconductor 系列独立于 CRAN 的一套专业仓库

一个容易被忽略的事实是:R 的包仓库是分层的。CRAN 收录通用包,Bioconductor 专注生物与医学,而 GitHub 上则汇集了大量尚未正式发布的开发版。日常优先用 CRAN,需要最新特性再考虑后两者,因为开发版意味着更少的测试和更多的坑。

从入门到精通:一条可执行的学习路线

把学习过程拆成五个阶段,每个阶段都有明确的产出物,比“看完多少集视频”更容易坚持。

阶段一:把环境跑通并写出第一条分析(约 1 周)

目标是消除“环境恐惧”。装好 R 和编辑器,学会用 install.packages() 装包、用 library() 载入、在控制台里试代码。能做出一张用内置数据画出的散点图就算过关。

阶段二:掌握数据结构与基础语法(约 2 到 3 周)

这是最需要耐心的阶段。重点是真正理解向量、因子、数据框和列表的区别,以及什么是向量化运算。这一阶段偷懒,后面每写三行代码就要查一次文档。

阶段三:用 tidyverse 打通数据全流程(约 1 个月)

围绕一份真实数据,完整走一遍「导入 → 清洗 → 转换 → 汇总 → 作图」的流程。吃透 filter、mutate、group_by、summarise 这几个动词和管道,再学 pivot_longer/pivot_wider 的形态转换。做完这一步,你已经能做日常的数据分析了。

阶段四:进入统计与建模(约 1 到 2 个月)

从线性回归开始,理解公式语法、系数解释、模型诊断。然后扩展到逻辑回归、常见假设检验,最后接触 tidymodels,建立起「划分数据、定义配方、训练、验证」的规范流程。这个阶段真正的瓶颈往往不是 R,而是统计学本身,需要同时补一点统计基础。

阶段五:走向精通(持续)

所谓精通,大致是这四件事:

  • 能写包:把自己的分析封装成可复用的函数和包,会写文档、会跑测试。用 devtools 与 usethis 把常用函数收进自己的包,是 R 程序员进阶的标志性动作。
  • 能锁环境:用 renv 锁定每个项目的包版本,保证分析结果可复现。renv 为每个项目创建独立的包库,记录精确版本到 renv.lock 文件,别人拿到你的项目后执行 renv::restore() 就能还原完全一致的环境。
  • 能交付报告:用 Quarto 把分析变成一份别人能一键复现的文档,而不是一堆脚本。
  • 能做工程:用 Git 管版本、用 Shiny 把结果做成可交互的产品。

学习资源的选择

  • 官方与教科书:R 官方手册(cran.r-project.org/manuals.html)是最权威的参考;《R for Data Science》第二版已全面改写为 Quarto 与管道语法,在线免费,网址是 r4ds.hadley.nz。
  • 进阶读物:《Advanced R》适合想弄清语言机制的人,《R Packages》讲怎么把自己的代码做成包。
  • 遇到问题:优先看函数的帮助文档(在函数名前加 ?),其次搜 Stack Overflow 的 R 标签,两者结合能解决九成以上的报错。聚合社区博客的 R-bloggers 也是追新特性时的好去处。

生态与就业:诚实版现状

R 的基本盘在统计相关领域:学术研究、生物统计(制药临床试验)、金融风控与市场分析里 R 是常客,数据分析师岗位中 R 与 SQL 的组合依旧常见。通用后端领域,R 的岗位远少于 Java 和 Python。

简单说:以统计为职业核心,R 值得深耕;追求通用性,可以 R 与 Python 双修,两者在 Positron 里可以无缝切换。

新手最容易踩的坑

把常见的坑集中列一下,能省下大量搜报错的时间。

  • 把 <- 当成 = 随便用。赋值推荐用 <-,= 留给函数传参和公式,混用会让代码意图模糊。
  • 忘记 NA 会传染。任何涉及缺失值的运算结果都是 NA,要用 na.rm = TRUE 或 is.na() 明确处理,而不是任由它扩散。
  • 把字符型和因子型搞混。建模时分类变量应该是因子,读数据时要注意字符串有没有被自动转成因子。
  • 该向量化的地方写循环。R 里边计算边增长向量(grow-by-loop)的效率极低,先分配好空间再填充是基本习惯。
  • 用 1:length(x) 做循环索引。长度为零时它会变成 1:0,正确写法是 seq_along(x)。
  • 忽略随机数种子。任何涉及随机的操作(抽样、划分数据集)之前先 set.seed(),否则结果不可复现。
  • 不设镜像源就装包。国内直连 CRAN 会慢到让人放弃,先配置好国内镜像。
  • 乱用 attach()。它会把数据框的列塞进全局环境,容易造成变量覆盖,用 with() 或直接 $ 取值更安全。
  • 忘记检查工作目录。getwd() 和 setwd() 带来的路径问题,是初学者报错的高频来源,用 RStudio 项目(Project)能从根本上避开。
  • 一次性梭哈写完再运行。数据分析是交互式的,写几行跑一次,错误的定位成本会低很多。

结语

R 的门槛不在语法,而在数据思维:把问题拆成一组对数据的变换,用向量和管道把它们串起来,再交给合适的模型。它的生态确实庞大到让人无从下手,但真正日常使用的核心其实不多,先集中吃透 tidyverse 和基础统计,余下的等到需要时再按图索骥。

如果只能记一句话,大约是:别急着学模型,先把数据结构、数据操作和可视化这三块地基打牢。地基稳了,后面无论是统计建模、机器学习还是可复现报告,都是在同一套思维方式上叠加而已。

发表评论

验证码图片,点击可更换