R Academy · 课时

解析 TSV 与定宽文件

使用 read_tsv() 和 read_fwf() 处理制表符分隔数据和定宽数据

第 2 / 4 课13 个步骤

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

超越 CSV:其他文件格式

并非所有表格数据都采用 CSV 格式。制表符分隔文件(TSV)、管道符分隔文件和定宽格式(FWF)文件在政府数据、旧式系统和科学数据库中都很常见。readr 软件包可以使用一致的语法处理这些格式。

library(readr)

# readr's flat file readers:
# read_csv()    - comma-separated
# read_csv2()   - semicolon-separated (European)
# read_tsv()    - tab-separated
# read_delim()  - any delimiter
# read_fwf()    - fixed-width format
# read_lines()  - raw text, one line per element

cat('All readr functions return tibbles with the same interface!')

read_tsv() — 制表符分隔值

read_tsv() 用于读取制表符分隔文件。它与 read_csv() 使用相同的参数,例如 col_types、na 和 skip。当数据中包含逗号(如地址、描述)时,优先使用 TSV 而不是 CSV。

library(readr)

# Simulated TSV using \t as delimiter
tsv_data <- 'name\tscore\tcity
Alice Smith\t85\tNew York, NY
Bob Jones\t92\tLos Angeles, CA
Carol White\t78\tChicago, IL'

# Note: cities contain commas — TSV handles this cleanly
df <- read_tsv(tsv_data, show_col_types=FALSE)
print(df)

read_delim() — 任意分隔符

read_delim(file, delim='|') 可以处理任意单字符分隔符。管道符分隔文件(|)在数据仓库和政府数据导出中很常见,因为管道符很少出现在数据本身中。

library(readr)

# Pipe-delimited data
pipe_data <- 'ID|Name|Department|Salary
1|Alice Smith|Engineering|95000
2|Bob Jones|Marketing|72000
3|Carol White|HR|65000'

df <- read_delim(pipe_data, delim='|', show_col_types=FALSE)
print(df)

使用 read_delim() 读取分号分隔文件

欧洲 CSV 文件通常使用分号作为分隔符,并使用逗号作为小数标记。read_csv2() 是 read_delim(delim=';', locale=locale(decimal_mark=',')) 的快捷方式,您也可以直接配置 read_delim()。

library(readr)

# European-style: semicolon delimiter, comma decimal
european_data <- 'name;price;quantity
Widget;9,99;100
Gadget;24,50;50
Sprocket;4,75;200'

# Method 1: read_csv2() shortcut
df1 <- read_csv2(european_data, show_col_types=FALSE)
print(df1)

# Method 2: explicit read_delim
# read_delim(data, delim=';', locale=locale(decimal_mark=','))

read_fwf() — 定宽格式

定宽文件没有分隔符,而是通过字符位置确定列。它们常见于旧式大型机导出数据和政府数据。使用 fwf_widths() 指定列宽,或使用 fwf_cols() 指定起始和结束位置。

library(readr)

# Fixed-width data (positions matter!)
fwf_data <- 'Alice    085NYC      
Bob      092LA       
Carol    078Chicago  '

# Column widths: name=9, score=3, city=10
df <- read_fwf(
  fwf_data,
  col_positions = fwf_widths(
    widths = c(9, 3, 10),
    col_names = c('name','score','city')
  ),
  show_col_types = FALSE
)

print(df)

使用 fwf_positions() 指定列的起始和结束位置

fwf_positions(start, end, col_names) 指定字符的确切起始和结束位置(索引从 1 开始)。当列宽不固定,或需要通过不指定某些列来跳过它们时,这种方式非常精确。

library(readr)

# Another fixed-width example using start/end positions
fwf_data <- '001ALICE   02024-01-15
002BOB     01   2024-02-20
003CAROL   03   2024-03-10'

df <- read_fwf(
  fwf_data,
  col_positions = fwf_positions(
    start = c(1, 4, 11, 14),
    end   = c(3, 10, 12, 23),
    col_names = c('id','name','score','date')
  ),
  show_col_types = FALSE
)

print(df)

fwf_empty() — 自动检测宽度

fwf_empty(file, col_names) 会根据空白间隔尝试自动检测列边界。请单独提供列名。对于间距一致、格式整洁的 FWF 文件,此函数效果最佳。

library(readr)

# Well-spaced fixed-width data
fwf_data <- 'name     score  grade
Alice    85     B
Bob      92     A
Carol    78     C
Dave     88     B'

# Auto-detect column positions from whitespace
df <- read_fwf(
  fwf_data,
  col_positions = fwf_empty(fwf_data, col_names=c('name','score','grade')),
  show_col_types = FALSE
)

print(df)

read_lines() — 解析原始文本

read_lines(file) 一次读取文本文件的一行,并返回字符向量。这是最低层级的读取函数,适用于需要在解析前预处理各行的情况(例如筛选注释或处理格式不一致的问题)。

library(readr)

# Read lines and filter manually
raw_text <- '# Comment line
# Another comment
name,score
Alice,85
Bob,92'

lines <- read_lines(raw_text)
print(lines)

# Filter out comment lines
clean_lines <- lines[!startsWith(lines, '#')]
df <- read_csv(paste(clean_lines, collapse='\n'), show_col_types=FALSE)
print(df)

使用 read_lines() 增量检查

read_lines(file, n_max=10) 可以在完整读取之前,仅预览任意文本文件开头的几行。这对于诊断编码问题、查找实际表头行或检测分隔符类型很有帮助。

library(readr)

# Preview first few lines before reading
sample_file <- 'METADATA: version 1.2
DATE: 2024-01-15
---
id,name,value
1,Alice,100
2,Bob,200'

# Inspect to find where the data starts
preview <- read_lines(sample_file, n_max=4)
print(preview)
# From this we know: skip=3, then read as CSV

处理编码问题

非 ASCII 字符(重音符号、非拉丁文字等)需要指定正确的编码。请在 read_csv() 或 read_delim() 中使用 locale(encoding='latin1') 或 locale(encoding='UTF-8')。默认编码为 UTF-8。

library(readr)

# Detect encoding of a file
# readr::guess_encoding('file.csv')  # Returns likely encodings

# Specify encoding explicitly
# df <- read_csv('data_latin1.csv',
#   locale = locale(encoding = 'latin1'))

# For UTF-8 with BOM (common in Windows exports):
# df <- read_csv('data_utf8bom.csv',
#   locale = locale(encoding = 'UTF-8-BOM'))

cat('Encoding matters for accented chars: \xc3\xa9 (UTF-8 for e-acute)\n')
print(guess_encoding(chartr('\xe9','e','caf\xe9')))

选择合适的读取函数

选择正确 readr 函数的快速指南:

  • 逗号 → read_csv()
  • 分号和欧洲小数格式 → read_csv2()
  • 制表符 → read_tsv()
  • 其他分隔符 → read_delim(delim='|')
  • 固定位置 → read_fwf()
  • 读取原始内容进行检查 → read_lines()
library(readr)

# Quick comparison of delimiters
csv_data  <- 'a,b,c\n1,2,3'
tsv_data  <- 'a\tb\tc\n1\t2\t3'
pipe_data <- 'a|b|c\n1|2|3'

read_csv(csv_data, show_col_types=FALSE)
read_tsv(tsv_data, show_col_types=FALSE)
read_delim(pipe_data, delim='|', show_col_types=FALSE)

快速检查

如果文件中的列由固定字符位置定义(没有分隔符),选择哪个 readr 函数最合适?

回顾:TSV 和定宽文件

非 CSV 平面文件格式的要点:

  • read_tsv() — 制表符分隔;适合数据中包含逗号的情况
  • read_delim(delim='|') — 任意单字符分隔符
  • read_csv2() — 分号分隔,并使用欧洲小数标记
  • read_fwf(fwf_widths(c(10,5,8))) — 根据列宽读取定宽文件
  • read_fwf(fwf_positions(start, end)) — 根据确切位置读取定宽文件
  • read_lines(file, n_max=10) — 在解析前检查原始行
  • 所有函数都使用相同的 col_types、na、skip 和 locale() 参数
library(readr)

# Pipe-delimited with custom NA values
df <- read_delim(
  'ID|Name|Score|City
  1|Alice|85|NYC
  2|Bob|N/A|N/A
  3|Carol|78|Chicago',
  delim = '|',
  na = c('', 'NA', 'N/A'),
  show_col_types = FALSE
)

print(df)
print(colSums(is.na(df)))
免费开始

用 AI 导师学习 R — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
43
课程
159

常见问题解答

「解析 TSV 与定宽文件」课时是免费的吗?

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

「解析 TSV 与定宽文件」这节课中我会学到什么?

使用 read_tsv() 和 read_fwf() 处理制表符分隔数据和定宽数据 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 R Academy 需要有经验吗?

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

「解析 TSV 与定宽文件」课时需要多长时间?

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

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

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

此课程中的所有课时

  1. 使用 read_csv() 读取 CSV 文件
  2. 解析 TSV 与定宽文件
  3. 使用 readxl 导入 Excel 文件
  4. 将数据写入多种格式
← 返回 R Academy