使用 R 的两种方式:控制台与脚本
R 有一个交互式的控制台(也就是 REPL:读取、求值、打印、循环):你输入一个表达式,R 立刻回答。在终端中输入 R,或者看 RStudio 底部的窗格,你会看到一个 > 提示符,每一行在你按下回车的瞬间就会运行。控制台是你探索的地方:摆弄数据、测试一行代码、查看结果。
R 脚本只是一个保存着 R 代码的纯文本文件,扩展名为 .R。分析工作真正存放在脚本里:它是一份可复现的配方,任何人(包括将来的你)从头运行到尾,都能得到相同的结果。
脚本没什么特别的。下面就是一个完整的脚本,运行一下:
下面的内容讲的都是把这样一个文件交给 R 运行的不同方式。
Rscript:在命令行中运行文件
R 安装时自带一个专门用于此事的命令行工具,叫 Rscript。在终端中,进入你的文件所在的文件夹:
Rscript summary.R
R 启动后,从头到尾运行这个文件,打印脚本输出的内容,然后退出。这是自动化的主力工具:定时任务(cron)、数据流程、服务器、CI,任何不需要人盯着运行代码的地方。
有一个行为每个人都会被它吓一次:在控制台中,输入像 avg 这样的单独表达式,会自动打印它的值。但在 Rscript 下,函数或循环内的单独表达式可能什么都不打印,所以脚本里要用显式的 cat() 或 print() 调用把意思说清楚。尽早养成这个习惯。
source():在 R 内部运行文件
已经在 R 会话中,想执行一个文件?那就用 source():
source("summary.R")
文件的每一行都会在你当前的会话中运行,脚本定义的所有东西,比如变量、函数,运行之后都会保留下来。这正是它的用途:source() 就是把你自己写的辅助函数加载到交互式会话中的方法。
默认情况下,除了显式的输出,source() 运行时是静默的。想看它运行的过程,就让它在执行时回显每一行:
source("summary.R", echo = TRUE)
注意这是相对路径:"summary.R" 的意思是“在当前工作目录中”,而工作目录在哪里,取决于你是怎么启动 R 的。当 source() 或 read.csv() 莫名其妙地找不到一个明明就在那里的文件时,几乎总是工作目录的问题,详见工作目录。
在 RStudio 中运行脚本
RStudio 用两个命令提供了这两种模式,值得把它们的区别真正弄明白:
- Run(Ctrl+Enter,macOS 上是 Cmd+Enter):在控制台中执行当前行或高亮选中的内容。这是探索模式:写一行,运行,看结果,再调整。
- Source(点击 Source 按钮,或按 Ctrl/Cmd+Shift+S):执行整个文件,和在控制台中调用
source()完全一样。
逐行 Run 的陷阱在于,你的控制台会话会不断积累状态:那些你后来修改或删除了的代码行所创建的变量仍然存在,于是脚本在你这里“能运行”,到别人那里就失败了。检验脚本的诚实做法是在一个全新的会话中 Source 它(Session → Restart R,然后 Source)。如果它能通过这一关,就是可复现的。
让脚本可以直接执行(macOS / Linux)
在类 Unix 系统上,你可以把一个 R 脚本变成一个独立的命令。在文件的最顶部写一行 shebang:
#!/usr/bin/env Rscript
cat("I am a self-running R script\n")
然后把它标记为可执行(只需要做一次),就能直接运行它:
chmod +x summary.R
./summary.R
shebang 告诉 shell 用哪个解释器来运行这个文件;env Rscript 会在那台机器的 PATH 中找到 Rscript,不管它装在哪里。因为这一行以 # 开头,R 本身会把它当作注释忽略掉。
给脚本传递参数
真正的脚本需要输入,比如一个文件名、一个日期、一个阈值,写在脚本名的后面传进去:
Rscript report.R sales.csv 2026
在脚本内部,commandArgs(trailingOnly = TRUE) 以字符向量的形式返回你传入的参数(trailingOnly = TRUE 会去掉解释器自己的内部参数,你几乎总是需要它):
# report.R
args <- commandArgs(trailingOnly = TRUE)
input_file <- args[1]
year <- as.numeric(args[2])
cat("Reading:", input_file, "\n")
cat("Filtering to year:", year, "\n")
所有参数都以文本形式传入,是 "2026",而不是 2026,所以做数学运算之前要用 as.numeric() 转换。我们可以用一个可运行的形式来模拟这个解析逻辑:
应该用哪一种?
- 探索数据、尝试想法 → 控制台,或 RStudio 中的 Run。
- 执行整个分析 → RStudio 中的 Source,或终端中的
Rscript。 - 把辅助函数加载到会话中 →
source("helpers.R")。 - 自动化、定时任务、数据流程 →
Rscript,用commandArgs()接收输入。
这些文件里面的代码该怎么写,是下一课的内容,详见 R 语法。
要点回顾
- 控制台用来探索;
.R脚本文件用来做可复现的分析。 Rscript file.R在命令行中运行脚本;source("file.R")在会话中运行它(加上echo = TRUE可以看到运行过程)。- 在 RStudio 中,Run 执行一行,Source 执行整个文件;在全新的会话中 Source,才是真正的可复现性测试。
#!/usr/bin/env Rscript加上chmod +x让脚本可以直接执行;commandArgs(trailingOnly = TRUE)以文本形式读取它的参数。
下一篇:R 的语法,用 <- 赋值、函数调用,以及“一切皆向量”的规则。
常见问题
怎么在命令行中运行 R 脚本?
使用 R 自带的 Rscript 命令:Rscript analysis.R。它会从头到尾运行这个文件,并打印脚本输出的所有内容。在定时任务、数据流程和服务器上运行 R,这是标准做法。
RStudio 中的 Run 和 Source 有什么区别?
Run(Ctrl/Cmd+Enter)只在控制台中执行当前行或选中的内容,非常适合探索阶段。Source 一次性执行整个文件,效果和 Rscript 一样。在一个干净的会话中 Source 你的脚本,才是检验它能否从头到尾正常运行的真正测试。
R 中的 source() 有什么作用?
source("script.R") 读取一个文件,并在你当前的 R 会话中执行其中的每一行,所以它定义的所有变量和函数之后你都可以使用。加上 echo = TRUE,还会在运行时打印每一行。
怎么给 R 脚本传递参数?
运行 Rscript script.R value1 value2,然后在脚本中用 args <- commandArgs(trailingOnly = TRUE) 读取它们。trailingOnly = TRUE 会去掉解释器自己用于记录的参数,只保留你传入的参数。所有参数都以文本形式传入,所以数字要用 as.numeric() 转换。