Судя по тому, как вы сформулировали свой вопрос, кажется, что вы знаете, что ваши данные «сбалансированы» (прямоугольные).
Вы ищет более быстрые варианты? Возможно, вы захотите объединить fread
с «data.table» с моей экспериментальной функцией 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
не имеет аргумента 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
. Это не так быстро, но по-прежнему выполняется прилично:
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