Прочитайте csv-файл, разделенный запятыми, с полями, содержащими запятые, используя fread в r

#r #csv #data.table #fread #comma

Вопрос:

У меня есть csv-файл, разделенный запятой. Однако есть поля, содержащие запятые, такие как названия компаний «Apple, Inc», и поля будут разделены на два столбца, что приводит к следующей ошибке при использовании fread.

«Остановились рано на строке 5. Ожидали 26 полей, но нашли 27».

Есть какие-либо предложения о том, как правильно загрузить этот файл? Заранее спасибо!

Добавить:

Примеры строк следующие. Похоже, что есть некоторые поля с запятой без кавычек. Но у них есть пробелы, следующие за запятой внутри поля.

 100,Microsoft,azure.com
300,IBM,ibm.com
500,Google,google.com
100,Amazon, Inc,amazon.com
400,"SAP, Inc",sap.com
 

Комментарии:

1. Если поля не защищены какими-либо кавычками, вы в некотором роде облажались, если только нет какой-либо другой структуры, которую вы можете использовать … можете ли вы опубликовать краткий/воспроизводимый пример (например, в виде текстового блока в формате кода)? Насколько велик файл (это определит практичность различных взломов/обходных путей) ?

2. Спасибо, Бен! За запятой внутри поля следует пробел. Файл не очень большой. Я думаю, что мне, возможно, потребуется изменить разделитель столбцов на точку с запятой.

3. Если есть поля без кавычек с запятой ( Amazon, Inc ), как вы узнаете, что они должны быть одним полем? Если вы хотите настроить их на основе пробелов, вам нужно прочитать их с помощью readLines и выполнить некоторую обработку текста.

4. Если изменение разделителя-это вариант, который был бы (безусловно) самым простым вариантом …

Ответ №1:

1) Используя тестовый файл, созданный в Примечании в конце, и предполагая, что в файле нет точек с запятой (используйте какой-либо другой символ, если он есть), прочитайте строки, замените первую и последнюю запятую точкой с запятой, а затем прочитайте его как файл, разделенный точкой с запятой.

 L <- readLines("firms.csv")
read.table(text = sub(",(.*),", ";\1;", L), sep = ";")
##    V1          V2         V3
## 1 100   Microsoft  azure.com
## 2 300         IBM    ibm.com
## 3 500      Google google.com
## 4 100 Amazon, Inc amazon.com
## 5 400    SAP, Inc    sap.com
 

2) Другой подход состоит в том, чтобы использовать gsub для замены каждой запятой, за которой следует пробел, точкой с запятой, за которой следует пробел, а затем использовать chartr для замены каждой запятой точкой с запятой и каждой точки с запятой, а затем прочитать ее в
виде файла, разделенного точкой с запятой.

 L <- readLines("firms.csv")
read.table(text = chartr(",;", ";,", gsub(", ", "; ", L)), sep = ";")
##    V1          V2         V3
## 1 100   Microsoft  azure.com
## 2 300         IBM    ibm.com
## 3 500      Google google.com
## 4 100 Amazon, Inc amazon.com
## 5 400    SAP, Inc    sap.com
 

3) Еще одна возможность, если таких строк не слишком много, — найти их, а затем поместить кавычки вокруг полей-нарушителей в текстовом редакторе. Тогда его можно будет прочитать в обычном режиме.

 which(count.fields("firms.csv", sep = ",") != 3)
## [1] 4
 

Примечание

 Lines <- '100,Microsoft,azure.com
300,IBM,ibm.com
500,Google,google.com
100,Amazon, Inc,amazon.com
400,"SAP, Inc",sap.com
'
cat(Lines, file = "firms.csv")
 

Ответ №2:

Для меня это прекрасно работает. Можете ли вы привести воспроизводимый пример?

 library(data.table)

# Create example and write out
df_out <- data.frame("X" = c("A", "B", "C"),
                     "Y"= c("a,A", "b,B", "C"))

write.csv(df_out, file = "df.csv", row.names = F)

# Read in CSV with fread
df_in <- fread("./df.csv")
df_in
 
    X   Y
1: A a,A
2: B b,B
3: C   C
 

Комментарии:

1. Спасибо, АдамК! Есть некоторые поля без кавычек, но с запятой внутри. Это должно быть проблемой для сообщения об ошибке.

2. ДА. Предупреждающее сообщение: В fread(«~/Desktop/fread_sample.txt», заголовок = F) : Остановлено рано в строке 4. Ожидалось 3 поля, но найдено 4. Рассмотрим fill=TRUE и comment.char=. Первая отброшенная непустая строка: <<100, Amazon, Inc, amazon.com><100, Amazon, Inc, amazon.com>>