#r #data.table
#r #data.table
Вопрос:
Я хочу прочитать файл CSV с помощью data.table
функции fread
. Файл CSV содержит большое количество записей с 9 столбцами, а затем большое количество записей с 10 столбцами. Использование аргумента fill=TRUE
не решает проблему. Вот несколько примеров данных, которые демонстрируют мою проблему:
library(data.table)
short <- rep("1,1,1", 1000)
long <- rep("1,1,1,2", 1000)
write(c(short, long), "shortLong.csv")
write(c(long, short), "longShort.csv")
Когда я читаю в файле, который имеет короткие длины столбцов, а затем длинные длины столбцов, я получаю эту ошибку:
fread("shortLong.csv", fill=TRUE)
Error in fread("shortLong.csv", fill = TRUE) :
Expecting 3 cols, but line 1001 contains text after processing all cols. Try again with fill=TRUE. Another reason could be that fread's logic in distinguishing one or more fields having embedded sep=',' and/or (unescaped) 'n' characters within unbalanced unescaped quotes has failed. If quote='' doesn't help, please file an issue to figure out if the logic could be improved
Однако, когда я читаю файл с длинной длиной столбца, а затем с короткой длиной столбца, он считывает файл без проблем и заполняет недостающие значения в коротких столбцах с помощью NA
, что я и хочу:
fread("longShort.csv", fill=TRUE)
V1 V2 V3 V4
1: 1 1 1 2
2: 1 1 1 2
3: 1 1 1 2
4: 1 1 1 2
5: 1 1 1 2
---
1996: 1 1 1 NA
1997: 1 1 1 NA
1998: 1 1 1 NA
1999: 1 1 1 NA
2000: 1 1 1 NA
Эта ошибка, по-видимому, вызвана большим количеством коротких столбцов перед длинными столбцами, так как при смешивании коротких и длинных столбцов проблем не возникло:
mixed <- rep(c("1,1,1", "1,1,1,2"), 1000)
write(mixed, "mixed.csv")
fread("mixed.csv", fill=TRUE)
V1 V2 V3 V4
1: 1 1 1 NA
2: 1 1 1 2
3: 1 1 1 NA
4: 1 1 1 2
5: 1 1 1 NA
---
1996: 1 1 1 2
1997: 1 1 1 NA
1998: 1 1 1 2
1999: 1 1 1 NA
2000: 1 1 1 2
Я подозреваю, что это различие в поведении может быть связано с тем, что fread
просматривает столбцы заранее, но не просматривает весь файл и устанавливает максимальный номер столбца на основе самого длинного из просмотренных (однако я не очень знаком с внутренней работой функции).
Есть ли какой-либо способ правильно прочитать мои данные с помощью fread
? Я думаю, что, вероятно, я мог бы собрать какое-нибудь хакерское решение и обойти fread
, но мне нравится производительность, и я не хочу резко замедлять свой код. Спасибо!
Комментарии:
1. К сожалению, я в Windows. Я надеюсь, что хотел бы иметь возможность решить эту проблему без необходимости изменять базовый файл вообще (в настоящее время я вручную вводил и добавлял одну из длинных строк в начало, что работает, но не то, что я бы предпочел)
Ответ №1:
Обратите внимание, что то, что у вас есть, не является файлом CSV, поскольку у него нет заголовка. Если мы добавим заголовок, это сработает. Сначала используйте fread
для чтения в виде одного поля в строке, задающего вектор символов Lines
. Исходя из этого, вычислите максимальное количество полей n
. Наконец, перечитайте Lines
после добавления к нему заголовка.
Lines <- fread("shortLong.csv", sep = "")[[1]]
n <- max(count.fields(textConnection(Lines), sep = ","))
fread(text = c(toString(1:n), Lines), header = TRUE, fill = TRUE)
Комментарии:
1. Спасибо за ответ! Первая строка выдала мне эту ошибку:
Error in fread("shortLong.csv", sep = "") : 'sep' must be 'auto' or a single character
2. Обновите data.table до последней версии или используйте какой-либо символ, который не отображается в файле.
3. В качестве аргумента в первой строке необходимо указать
header=FALSE
, иначе первая строка будет интерпретирована как имя столбца, а конечная таблица будет короче на 1 строку