我的文件看起来像:
a 1,2,3,5
b 4,5,6,7
c 5,6,7,8
...
第1个和第2个之间的分隔符是'\ t',其他分隔符是逗号。如何将此类数据集读取为具有5个字段的数据框。
答案 0 :(得分:21)
我可能会这样做。
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
解压缩一下:
readLines()
将文件作为字符向量读入R,每行包含一个元素。gsub(",", "\t", ...)
用标签替换每个逗号,以便现在我们只有一种分隔字符的行。text =
的{{1}}参数让它知道您正在传递一个要直接读取的字符向量(而不是包含文本数据的文件的名称) 答案 1 :(得分:8)
根据您表达问题的方式判断,您似乎知道您的数据已经平衡了#34; (矩形)。
您在寻找更快捷的选择吗?您可能希望合并来自" data.table"的fread
我的实验concat.split.DT
function。
解决方案看起来像(将" "
替换为"\t"
选项卡):
concat.split.DT(fread("yourfile.txt", sep = " ", header=FALSE), "V2", ",")
让我们编写一些数据:
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
乔希的回答:
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
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
虽然它并不适用于您的问题,但我应该提及这一点,以便其他可能需要解决类似问题的人受益:
上述一个限制是concat.split.DT
仅处理&#34;平衡&#34;数据。 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")
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
在这种情况下, concat.split.DT
会给您一个令人讨厌的错误,但您可以尝试我的cSplit
function。它不是那么快,但仍然表现得很好:
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
答案 2 :(得分:0)
Scanner scan = new Scanner(file);
while (scan.hasNextLine()) {
String[] a = scan.nextLine().replace("\\t", ",").split(",");
//do something with the array
}
scan.close();
这样做了: