如何在R中正确导入列数不固定的无表头多列TXT数据集?
解决无表头、列数不一致的TXT数据导入错位问题
问题背景
无表头TXT数据集存在部分行因缺少rg:字段导致列数不一致的情况,使用readr::read_table()导入时出现值列错位、数据混杂的问题。
数据集示例:
>chr22_KI270739v1_random AC:KI270739.1 gi:568335374 LN:73985 rg:chr22 rl:unlocalized M5:760fbd73515fedcc9f37737c4a722d6a AS:GRCh38 >chrY_KI270740v1_random AC:KI270740.1 gi:568335373 LN:37240 rg:chrY rl:unlocalized M5:69e42252aead509bf56f1ea6fda91405 AS:GRCh38 >chrUn_KI270302v1 AC:KI270302.1 gi:568335372 LN:2274 rl:unplaced M5:ee6dff38036f7d03478c70717643196e AS:GRCh38 >chrUn_KI270304v1 AC:KI270304.1 gi:568335371 LN:2165 rl:unplaced M5:9423c1b46a48aa6331a77ab5c702ac9d AS:GRCh38
原导入代码:
all_chr_GATKbundle <- read_table("all_ch_GATKbundle.txt", col_names = F)
导入后出现列错位,例如部分行的M5:字段被挤入错误列。
解决方案
方法1:按行读取后拆分键值对(推荐)
由于每条记录的字段均为key:value格式,无论是否缺失rg,都可按键值对拆分后整理为规范数据框:
library(tidyverse) # 按行读取所有内容 lines <- read_lines("all_ch_GATKbundle.txt") # 处理每行:拆分字段→提取键值对→合并为数据框 all_chr_GATKbundle <- lines %>% map_dfr(function(line) { # 按空格拆分字段(忽略连续空格) fields <- str_split(line, "\\s+")[[1]] # 拆分每个字段的key与value key_value <- str_split(fields, ":", n = 2) # 转换为键值对列表后转成数据框行 as_tibble(set_names(map(key_value, 2), map(key_value, 1))) })
该方法会自动为缺失字段(如rg)填充NA,所有值将精准对应到正确列。
方法2:统一每行的列数后导入
若坚持使用read_table,可先预处理每行,为缺失rg的行补全占位符:
# 读取所有行 lines <- read_lines("all_ch_GATKbundle.txt") # 为无rg:的行在LN:后插入rg:NA占位符 processed_lines <- str_replace(lines, "(LN:\\d+)\\s+(rl:)", "\\1 rg:NA \\2") # 写入临时文件后导入 write_lines(processed_lines, "temp_processed.txt") all_chr_GATKbundle <- read_table("temp_processed.txt", col_names = c("chr_id", "AC", "gi", "LN", "rg", "rl", "M5", "AS"))
处理后所有行均为8列,导入后不会出现错位,缺失的rg值为NA。
方法3:使用基础R的read.delim自动填充
基础R的read.delim支持fill=TRUE自动填充缺失列,需指定正确分隔符:
all_chr_GATKbundle <- read.delim("all_ch_GATKbundle.txt", header = FALSE, sep = " ", fill = TRUE, stringsAsFactors = FALSE, strip.white = TRUE) # 手动命名列 colnames(all_chr_GATKbundle) <- c("chr_id", "AC", "gi", "LN", "rg", "rl", "M5", "AS")
注意:该方法依赖缺失字段的位置固定(如均缺失第5列rg),否则仍可能错位,可靠性不如方法1。
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

