0Pricing
R Academy · 课时

工作目录与文件路径

使用 getwd()、setwd() 和 here() 创建可靠的跨平台路径

工作目录与文件路径 是 CoddyKit 上的免费 R Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。

什么是工作目录

工作目录是 R 在您使用相对路径引用文件时作为起点的文件夹。当您未提供完整路径时,R 默认会在此位置查找文件并将文件写入此位置。每个 R 会话在任意时刻都恰好有一个工作目录。

# getwd() returns the current working directory
current_dir <- getwd()
cat('Working directory:', current_dir)

# All relative file references start from this location:
# read.csv('data.csv')         <- looks in current_dir/data.csv
# source('R/helpers.R')        <- looks in current_dir/R/helpers.R

setwd()——更改工作目录

setwd() 会更改当前 R 会话的工作目录。它会以不可见方式返回之前的工作目录,这对于恢复原状态很有用。注意:在基于项目的工作流程中,不建议在脚本中使用 setwd()。

# Set a new working directory
old_dir <- setwd('/tmp')
cat('Now in:', getwd(), '\n')

# Restore original directory
setwd(old_dir)
cat('Restored to:', getwd(), '\n')

# Common anti-pattern (breaks on other machines):
# setwd('/Users/alice/Desktop/my_project')  <- hardcoded!

# Better: use RStudio Projects which set wd automatically

file.path()——构建可移植路径

file.path() 会使用适合操作系统的分隔符连接各个组成部分,从而构建文件路径(Mac/Linux 使用 /,Windows 使用 \)。为确保跨平台兼容性,请始终使用它,而不要进行字符串拼接。

# Build a path from components
data_path <- file.path('data', 'raw', 'sales.csv')
cat('Path:', data_path)
# On Unix:    data/raw/sales.csv
# On Windows: data\raw\sales.csv

# Multiple levels
output_file <- file.path('output', '2024', 'Q1', 'report.pdf')
cat('Output:', output_file)

# Combine with getwd() for a full absolute path
full_path <- file.path(getwd(), 'data', 'sales.csv')
cat('Full path:', full_path)

normalizePath()——解析为绝对路径

normalizePath() 会将相对路径转换为规范的绝对路径,同时解析 .(当前目录)和 ..(父目录)组成部分。当您需要存储或记录明确无歧义的文件位置时,这个函数必不可少。

# Resolve relative paths to absolute
abs_path <- normalizePath('.')
cat('Absolute cwd:', abs_path, '\n')

# Resolve a relative path
data_abs <- normalizePath(file.path('..', 'data', 'sales.csv'),
                          mustWork = FALSE)
cat('Resolved:', data_abs, '\n')

# mustWork = FALSE: do not error if file does not exist yet
# mustWork = TRUE (default): error if path does not exist

# Useful for building reliable log messages or config files
cat('normalizePath demo complete')

dirname() 和 basename()

dirname() 提取路径中的目录部分,而 basename() 提取文件名部分。它们分别对应 Unix dirname 和 basename shell 命令在 R 中的功能。

path <- '/Users/alice/projects/analysis/data/sales_2024.csv'

# Extract the directory
folder <- dirname(path)
cat('Directory:', folder, '\n')
# /Users/alice/projects/analysis/data

# Extract the file name
filename <- basename(path)
cat('File name:', filename, '\n')
# sales_2024.csv

# Remove file extension
name_only <- tools::file_path_sans_ext(filename)
cat('Name only:', name_only)

file.exists()——读取前进行检查

尝试读取文件前,请始终先检查文件是否存在,以避免难以理解的错误消息。file.exists() 返回 TRUE 或 FALSE,可同时用于文件和目录。

data_file <- file.path('data', 'sales.csv')

# Check existence before reading
if (file.exists(data_file)) {
  cat('File found, loading...\n')
  # df <- read.csv(data_file)
} else {
  cat('File not found:', data_file, '\n')
  stop('Cannot proceed without data file.')
}

# Check multiple files at once
files <- c('data/a.csv', 'data/b.csv', 'data/c.csv')
exists_vec <- file.exists(files)
cat('Files found:', sum(exists_vec), 'of', length(files))

Sys.getenv()——环境变量路径

环境变量用于存储系统级路径,例如主目录、临时文件夹和自定义应用路径。Sys.getenv() 可以读取这些值,使您的代码无需硬编码路径即可适应不同系统。

# Get the home directory
home_dir <- Sys.getenv('HOME')
cat('Home:', home_dir, '\n')

# Get the temp directory
tmp_dir <- Sys.getenv('TMPDIR')
cat('Temp:', tmp_dir, '\n')

# Custom environment variable (set in .Renviron)
data_root <- Sys.getenv('DATA_ROOT', unset = '/default/data')
cat('Data root:', data_root, '\n')

# Use env vars to build portable paths
config_file <- file.path(home_dir, '.config', 'myapp', 'settings.json')
cat('Config path:', config_file)

path.expand()——展开波浪号

在类 Unix 系统中,波浪号 ~ 是主目录的简写,但 R 的文件函数并不总是会自动展开它。path.expand() 会将 ~ 替换为实际的主目录路径。

# Expand tilde to full home path
short_path <- '~/.Rprofile'
full_path  <- path.expand(short_path)
cat('Expanded:', full_path)
# e.g. /Users/alice/.Rprofile

# Useful when passing paths to external tools or logging
config_dir <- path.expand('~/.config/R')
cat('Config dir:', config_dir)

# Can expand multiple paths at once
paths <- c('~/data', '~/output', '~/scripts')
expanded <- path.expand(paths)
cat(expanded, sep = '\n')

使用 list.files() 列出文件

list.files()(别名为 dir())会列出目录中的文件,也可以选择按模式筛选,并选择是否返回完整路径。当您需要处理文件夹中的多个文件时,它非常不可或缺。

# List all files in current directory
all_files <- list.files('.')
cat('Files found:', length(all_files), '\n')

# Filter by extension
csv_files <- list.files('data', pattern = '\\.csv$', full.names = TRUE)
cat('CSV files:',  length(csv_files), '\n')

# Recursive: include subdirectories
r_files <- list.files('R', pattern = '\\.R$',
                       full.names = TRUE, recursive = TRUE)
cat('R scripts:', length(r_files))

创建和删除路径

R 提供了用于创建目录和管理文件的内置函数。使用 dir.create() 创建新文件夹(使用 recursive = TRUE 可以创建嵌套路径),并使用 file.remove() 清理临时文件。

# Create a directory (will not error if it already exists)
dir.create('output/figures', recursive = TRUE, showWarnings = FALSE)
cat('Directory created\n')

# Create a temporary file
tmp_file <- tempfile(fileext = '.csv')
write.csv(data.frame(x = 1:3), tmp_file, row.names = FALSE)
cat('Temp file:', tmp_file, '\n')

# Remove the file when done
if (file.remove(tmp_file)) {
  cat('Temp file cleaned up')
}

here 包——相对于项目的路径

here 包优雅地解决了工作目录问题。无论您从项目中的哪个位置调用 here::here(),它都会始终构建相对于项目根目录的路径(项目根目录是 .Rproj 文件所在的位置)。

# install.packages('here')
# library(here)

# Always resolves from project root:
# here('data', 'raw', 'sales.csv')
# here('R', 'helpers.R')
# here('output', 'report.html')

# Without here: setwd() headaches when script is in a subfolder
# With here: same path works from any subfolder

# Demonstrate base-R equivalent approach:
project_root <- normalizePath(file.path(getwd(), '..'), mustWork = FALSE)
data_path    <- file.path(project_root, 'data', 'sales.csv')
cat('Data path:', data_path)

快速检查

您有一个路径字符串 'data/raw/../clean/sales.csv'。要将其解析为整洁、规范的绝对路径,您会使用哪个函数?

文件路径——要点总结

稳健地处理文件路径对于编写可复现的 R 脚本至关重要:

  • getwd() / setwd()——获取和设置工作目录
  • file.path('a', 'b', 'c.csv')——构建可跨操作系统使用的路径
  • normalizePath(path, mustWork = FALSE)——解析为绝对路径
  • dirname() / basename()——将路径拆分为文件夹和文件名
  • file.exists()——读取前进行检查
  • Sys.getenv('HOME')——通过环境变量访问系统路径
  • path.expand('~')——将波浪号展开为主目录
  • list.files(pattern = '\.csv$')——按扩展名查找文件
  • dir.create(recursive = TRUE)——安全地创建嵌套目录
  • 在 RStudio 项目中使用 here 包处理相对于项目的路径
# Robust file loading pattern:
data_file <- file.path('data', 'raw', 'sales.csv')

if (!file.exists(data_file)) {
  stop(paste('Missing file:', normalizePath(data_file, mustWork = FALSE)))
}

# df <- read.csv(data_file)
cat('File path:', data_file, '\n')
cat('Full path:', normalizePath(data_file, mustWork = FALSE))

常见问题解答

「工作目录与文件路径」课时是免费的吗?

是的 — 「工作目录与文件路径」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。

「工作目录与文件路径」这节课中我会学到什么?

使用 getwd()、setwd() 和 here() 创建可靠的跨平台路径 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 R Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「工作目录与文件路径」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 R Academy 课中编写并运行代码吗?

能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用 source() 加载脚本
  2. 注释、风格与可读性
  3. 工作目录与文件路径
  4. R 项目与工作区管理
← 返回 R Academy