Быстрое чтение разных типов данных с помощью одной и той же команды, лучшее угадывание разделителя

У меня есть данные LD, иногда необработанный выходной файл из PLINK как ниже (обратите внимание на пробелы — используются для красивого вывода, также обратите внимание на начальные и конечные пробелы):

write.table(read.table(text="
 CHR_A     BP_A          SNP_A  CHR_B         BP_B          SNP_B           R2 
 1    154834183      rs1218582      1    154794318      rs9970364    0.0929391 
 1    154834183      rs1218582      1    154795033     rs56744813      0.10075 
 1    154834183      rs1218582      1    154797272     rs16836414     0.106455 
 1    154834183      rs1218582      1    154798550    rs200576863    0.0916789 
 1    154834183      rs1218582      1    154802379     rs11264270     0.176911 ",sep="x"),
          "Type1.txt",col.names=FALSE,row.names=FALSE,quote=FALSE)  

Или красиво разделенный табуляцией файл:

write.table(read.table(text="
CHR_A BP_A SNP_A CHR_B BP_B SNP_B R2
1 154834183 rs1218582 1 154794318 rs9970364 0.0929391
1 154834183 rs1218582 1 154795033 rs56744813 0.10075
1 154834183 rs1218582 1 154797272 rs16836414 0.106455
1 154834183 rs1218582 1 154798550 rs200576863 0.0916789
1 154834183 rs1218582 1 154802379 rs11264270 0.176911", sep=" "),
            "Type2.txt",col.names=FALSE,row.names=FALSE,quote=FALSE,sep="\t")

read.csv работает для обоих типов данных:

read.csv("Type1.txt", sep="")
read.csv("Type2.txt", sep="")

fread работает только для Type2:

fread("Type1.txt")
fread("Type2.txt")

Файлы большие, в миллионах строк, поэтому нельзя использовать параметр read.csv. Есть ли способ улучшить fread угадай? Другие предложения по пакету/функции?

Я мог бы использовать readLines, а затем угадать тип файла, или очистить файл с помощью системного вызова, а затем fread, но это добавит накладные расходы, которых я пытаюсь избежать.

Изменить: информация о сеансе

R version 3.2.0 (2015-04-16)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

person zx8754    schedule 26.06.2015    source источник
comment
Что касается другого вопроса, я заметил, что fread не работает там, где работает read.csv/read.table. Вы работаете на линуксе?   -  person akrun    schedule 26.06.2015
comment
@akrun см. редактирование, я на Windows. Вы предлагаете, чтобы у меня не было этой проблемы в Linux?   -  person zx8754    schedule 26.06.2015
comment
Я говорю, что это будет работать при подключении к awk. то есть fread("awk '{$1=$1}1' Type1.txt")   -  person akrun    schedule 26.06.2015
comment
О, я понимаю, это то, что я имел в виду под ...system call then fread..., которого я хочу избежать.   -  person zx8754    schedule 26.06.2015
comment
Одна и та же команда работает как для Type1, так и для Type2.txt. Но я не знаю, как изменить это для Windows   -  person akrun    schedule 26.06.2015
comment
Накладные расходы при запуске через awk будут минимальными. За stackoverflow.com/questions/22229109/ Я думаю, что awk или sed - ваши единственные варианты на данный момент.   -  person Nick Kennedy    schedule 26.06.2015


Ответы (3)


Исправлено в версии для разработчиков, v1.9.5. Либо используйте devel (/upgrade), либо подождите некоторое время, пока он попадет в CRAN как v1.9.6:

require(data.table) # v1.9.5+
ans <- fread("Type1.txt")
#    CHR_A      BP_A     SNP_A CHR_B      BP_B       SNP_B        R2
# 1:     1 154834183 rs1218582     1 154794318   rs9970364 0.0929391
# 2:     1 154834183 rs1218582     1 154795033  rs56744813 0.1007500
# 3:     1 154834183 rs1218582     1 154797272  rs16836414 0.1064550
# 4:     1 154834183 rs1218582     1 154798550 rs200576863 0.0916789
# 5:     1 154834183 rs1218582     1 154802379  rs11264270 0.1769110

fread() получил strip.white (по умолчанию = TRUE) среди других аргументов / исправлений ошибок. Дополнительную информацию см. в файле README на странице проекта.


Типы также распознаются правильно.

sapply(ans, class)
#       CHR_A        BP_A       SNP_A       CHR_B        BP_B       SNP_B          R2 
#   "integer"   "integer" "character"   "integer"   "integer" "character"   "numeric" 
person Arun    schedule 17.09.2015

Я не думаю, что fread обладает такой способностью изначально. Однако опция системной команды будет работать, и дополнительные затраты на копирование обычно того стоят:

fread("powershell \"cat Type1.txt | % { $_ -replace ' +',',' } | % { $_ -replace '^,|,$','' }\"")
#   CHR_A      BP_A     SNP_A CHR_B      BP_B       SNP_B        R2
#1:     1 154834183 rs1218582     1 154794318   rs9970364 0.0929391
#2:     1 154834183 rs1218582     1 154795033  rs56744813 0.1007500
#3:     1 154834183 rs1218582     1 154797272  rs16836414 0.1064550
#4:     1 154834183 rs1218582     1 154798550 rs200576863 0.0916789
#5:     1 154834183 rs1218582     1 154802379  rs11264270 0.1769110
person eddi    schedule 26.06.2015

Вы можете попробовать пакетный ридер. Доступно на Cran или на github.

Прочитайте виньетки, если это поможет вам. Я считаю, что он правильно читает большинство CSV, включая даты, и нет необходимости указывать stringsAsFactors = False.

Но прочитайте сравнение с fread()

person phiver    schedule 26.06.2015
comment
fread() экономит вашу работу, автоматически угадывая разделитель, есть ли у файла заголовок, сколько строк пропускать по умолчанию и многое другое. Readr заставляет вас указывать эти параметры. - Я хочу избежать указания разделителя, и мне нужна функция, чтобы угадать его правильно. - person zx8754; 26.06.2015