我有一个文件看起来像:
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()让它知道你传递一个特征向量来直接读取(而不是文件名包含文本数据).从您对问题的表达方式来判断,您似乎知道您的数据是"平衡的"(矩形).
您在寻找更快捷的选择吗?您可能希望将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)