如何使用不同的分隔符读取数据?

yli*_*gle 9 r read.table

我有一个文件看起来像:

a 1,2,3,5
b 4,5,6,7
c 5,6,7,8
...
Run Code Online (Sandbox Code Playgroud)

第1和第2之间的分隔符是'\ t',其他分隔符是逗号.如何将此类数据集读取为具有5个字段的数据帧.

Jos*_*ien 24

我可能会这样做.

read.table(text = gsub(",", "\t", readLines("file.txt")))
  V1 V2 V3 V4 V5
1  a  1  2  3  5
2  b  4  5  6  7
3  c  5  6  7  8
Run Code Online (Sandbox Code Playgroud)

解压缩一下:

  • readLines() 将文件作为字符向量读入R,每行有一个元素.
  • gsub(",", "\t", ...) 用标签替换每个逗号,这样我们现在只有一种分隔字符.
  • text =参数read.table()让它知道你传递一个特征向量来直接读取(而不是文件名包含文本数据).


A5C*_*2T1 8

"平衡"数据

从您对问题的表达方式来判断,您似乎知道您的数据是"平衡的"(矩形).

您在寻找更快捷的选择吗?您可能希望将fread"data.table"与我的实验concat.split.DT函数结合起来.

该解决方案将看起来像(替换" ""\t"的标签):

concat.split.DT(fread("yourfile.txt", sep = " ", header=FALSE), "V2", ",")
Run Code Online (Sandbox Code Playgroud)

让我们编写一些数据:

x <- c("a\t1,2,3,5", "b\t4,5,6,7","c\t5,6,7,8")
X <- c(replicate(10000, x))
temp <- tempfile()
writeLines(X, temp, sep="\n") ## Write it to a temporary file
Run Code Online (Sandbox Code Playgroud)

乔希的回答:

system.time(out1 <- read.table(text = gsub(",", "\t", readLines(temp))))
#    user  system elapsed 
#   0.679   0.000   0.676 
head(out1)
#   V1 V2 V3 V4 V5
# 1  a  1  2  3  5
# 2  b  4  5  6  7
# 3  c  5  6  7  8
# 4  a  1  2  3  5
# 5  b  4  5  6  7
# 6  c  5  6  7  8
dim(out1)
# [1] 30000     5
Run Code Online (Sandbox Code Playgroud)

fread+ concat.split.DT(这就像使用fread两次,但仍然超级快):

system.time(out2 <- concat.split.DT(fread(temp, sep = "\t", header=FALSE), "V2", ","))
#    user  system elapsed 
#   0.027   0.000   0.028 
head(out2)
#    V1 V2_1 V2_2 V2_3 V2_4
# 1:  a    1    2    3    5
# 2:  b    4    5    6    7
# 3:  c    5    6    7    8
# 4:  a    1    2    3    5
# 5:  b    4    5    6    7
# 6:  c    5    6    7    8
dim(out2)
# [1] 30000     5
Run Code Online (Sandbox Code Playgroud)

"不平衡"数据

虽然它不适用于您的问题,但我应该提及这可能是为了其他可能需要解决类似问题的人的利益:

上述的一个限制是concat.split.DT仅处理"平衡"数据.fread没有一个fill类似的论点read.table(我似乎记得在某处读它很可能没有这样的论点).

这是我所说的不平衡的一个例子:

x2 <- c("a\t1,2,3,5,6,7", "b\t4,5,6,7","c\t5,6,7,8,9,10,11,12,13")
X2 <- c(replicate(10000, x2))
temp2 <- tempfile()
writeLines(X2, temp2, sep="\n")
Run Code Online (Sandbox Code Playgroud)

read.table可以使用fill = TRUE参数处理:

system.time(out1b <- read.table(text = gsub(",", "\t", readLines(temp2)), fill=TRUE))
#    user  system elapsed 
#   1.151   0.000   1.152 
head(out1b)
#   V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
# 1  a  1  2  3  5  6  7 NA NA  NA
# 2  b  4  5  6  7 NA NA NA NA  NA
# 3  c  5  6  7  8  9 10 11 12  13
# 4  a  1  2  3  5  6  7 NA NA  NA
# 5  b  4  5  6  7 NA NA NA NA  NA
# 6  c  5  6  7  8  9 10 11 12  13
Run Code Online (Sandbox Code Playgroud)

concat.split.DT在这种情况下会给你一个讨厌的错误,但你可以尝试我的cSplit功能.它不是那么快,但仍然表现得很好:

system.time(out2b <- cSplit(fread(temp2, sep = "\t", header=FALSE), "V2", ","))
#    user  system elapsed 
#   0.393   0.004   0.399 
head(out2b)
#    V1 V2_1 V2_2 V2_3 V2_4 V2_5 V2_6 V2_7 V2_8 V2_9
# 1:  a    1    2    3    5    6    7   NA   NA   NA
# 2:  b    4    5    6    7   NA   NA   NA   NA   NA
# 3:  c    5    6    7    8    9   10   11   12   13
# 4:  a    1    2    3    5    6    7   NA   NA   NA
# 5:  b    4    5    6    7   NA   NA   NA   NA   NA
# 6:  c    5    6    7    8    9   10   11   12   13
Run Code Online (Sandbox Code Playgroud)