Разбор CSV с нерегулярными правилами цитирования с использованием readr - PullRequest
0 голосов
/ 11 февраля 2019

У меня странный CSV, который я не могу разобрать с readr.Давайте назовем это data.csv.Это выглядит примерно так:

name,info,amount_spent
John Doe,Is a good guy,5412030
Jane Doe,"Jan Doe" is cool,3159
Senator Sally Doe,"Sally "Sal" Doe is from New York, NY",4451

Если бы все строки были похожи на первую строку ниже строки столбцов - два символьных столбца, за которыми следовал целочисленный столбец - это было бы легко проанализировать с помощью read_csv:

df <- read_csv("data.csv")

Однако некоторые строки отформатированы так же, как и вторая, в том, что второй столбец («информация») содержит строку, часть которой заключена в двойные кавычки, а часть - нет.Это делает так, что read_csv не считывает запятую после слова cool в качестве разделителя, и вся следующая строка добавляется к ошибочной ячейке.

Решением для такого рода проблемы является передача FALSE до аргумента escape_double в read_delim(), например:

df <- read_delim("data.csv", delim = ",", escape_double = FALSE)

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

Я прочитал документацию по readr, но пока не нашел решения, которое бы анализировало строки обоих типов.

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Вы можете использовать регулярное выражение, которое разделяется на запятую (с использованием (*SKIP)(*FAIL)):

input <- c('John Doe,Is a good guy,5412030', 'Jane Doe,"Jan Doe" is cool,3159',
           'Senator Sally Doe,"Sally "Sal" Doe is from New York, NY",4451')

lst <- strsplit(input, '"[^"]*"(*SKIP)(*FAIL)|,', perl = T)

(df <- setNames(as.data.frame(do.call(rbind, lst)), c("name","info","amount_spent")))

Это дает

               name                                   info amount_spent
1          John Doe                          Is a good guy      5412030
2          Jane Doe                      "Jan Doe" is cool         3159
3 Senator Sally Doe "Sally "Sal" Doe is from New York, NY"         4451

См. Демонстрацию для выражения на regex101.com .

0 голосов
/ 12 февраля 2019

Вот что сработало у меня с указанным примером.

Используется read.csv, а не read_csv.Это означает, что я использую фрейм данных, а не тиббл.

#Read the csv, just turned the table you had as an example to a csv.
#That resulted as a csv with one column
a <- read.csv(file = "Book1.csv", header=T) 

#Replace the comma in the third(!) line with just space
a[,1] <-  str_replace_all(as.vector(a[,1]), ", ", " ")

#Use seperate from the tidyer package to split the column to three columns
#and convert to a tibble
a <- a %>% separate(name.info.amount_spent, c("name", "info", "spent"), ",")%>%
as_tibble(a)
glimpse(a)
 $name  <chr> "John Doe", "Jane Doe", "Senator Sally Doe"
 $info  <chr> "Is a good guy", "\"Jan Doe\" is cool", "\"Sally \"Sal\" Doe is from New York NY\""
 $spent <chr> "5412030", "3159", "4451"
...