[英]How to read data with different separators?
我有一個文件看起來像:
a 1,2,3,5
b 4,5,6,7
c 5,6,7,8
...
第1和第2之間的分隔符是'\\ t',其他分隔符是逗號。 如何將此類數據集讀取為具有5個字段的數據幀。
我可能會這樣做。
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", ...)
用標簽替換每個逗號,所以現在我們只有一種分隔字符。 read.table()
的text =
參數讓它知道你傳遞的字符向量是直接讀取的(而不是包含文本數據的文件的名稱)。 從您對問題的表達方式來判斷,您似乎知道您的數據是“平衡的”(矩形)。
您在尋找更快捷的選擇嗎? 您可能希望將來自“data.table”的fread
與我的實驗性concat.split.DT
函數結合起來。
該解決方案看起來是這樣的(替代" "
用"\\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
僅處理“平衡”數據。 fread
沒有像read.table
那樣的fill
參數(我似乎記得在某個地方讀過它很可能沒有這樣的參數)。
這是我所說的不平衡的一個例子:
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
函數 。 它不是那么快,但仍然表現得很好:
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
Scanner scan = new Scanner(file);
while (scan.hasNextLine()) {
String[] a = scan.nextLine().replace("\\t", ",").split(",");
//do something with the array
}
scan.close();
這樣做:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.