Как предотвратить использование разделителя при вводе `read.csv`? - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть CSV-файл, как показано ниже:

id,age,note
241,18,I am handsome,I am 18.
242,19, <ul>
    <li>
        <strong>I like music</strong><br />
        Talor swift:I kike Talor,I like her concert{smile}.<br />
        Beyonce:I have 3 albums.</li>
    <ul>
243,17,<I write something sn2370292kl@$^&,hahhaha

Голова id,age,note, note - строка, вводимая студентами, может быть любым символом.

В read.csv("qlist.csv",header=TRUE, sep=",",quote ="\"",na.strings = c(""," "),check.names=TRUE,fill=FALSE,strip.white = FALSE,comment.char = "",allowEscapes = FALSE,stringsAsFactors =FALSE,skipNul = FALSE), я думаю, я не могу использовать , в качестве разделителя из-за I am handsome,I am 18.

Тогда, какой разделитель можно использовать, чтобы запретить разделитель входной части?

Кроме того, я попробовал ответ Г. Гротендика:

> version
               _                           
platform       x86_64-w64-mingw32          
arch           x86_64                      
os             mingw32                     
system         x86_64, mingw32             
status                                     
major          3                           
minor          5.3                         
year           2019                        
month          03                          
day            11                          
svn rev        76217                       
language       R                           
version.string R version 3.5.3 (2019-03-11)
nickname       Great Truth                 
> Lines <- 'id,age,note
+ 241,18,I am handsome,I am "18".
+ 242,19, <ul>
+ <li>
+ <strong>I like music</strong><br />
+ Talor swift:I kike Talor,I like her concert{smile}.<br />
+ Beyonce:I have 3 albums.</li>
+ <ul>
+ 243,17,<I write something sn2370292kl@$^&,hahhaha'
> L <- readLines(textConnection(Lines))
> L2 <- lapply(split(L, cumsum(grepl("^\\S", L))), function(x) {
+     x <- gsub('"', '""', x)
+     x[1] <- sub('^(.*?,.*?,)', '\\1"', x[1])
+     x[length(x)] <- paste0(x[length(x)], '"')
+     x
+ })
> DF <- read.csv(text = unname(unlist(L2)))
Warning message:
In scan(file = file, what = what, sep = sep, quote = quote, dec = dec,  :
  EOF within quoted string
> dim(DF)
[1] 5 3

1 Ответ

2 голосов
/ 21 апреля 2020

Нам нужно иметь кавычки вокруг многострочных полей. Сначала прочитайте файл, используя readLines, разбейте его на логические записи и поместите двойные кавычки вокруг третьего поля. Затем прочитайте это с read.csv.

Мы предположили, что строки, соответствующие шаблону grep, определенному в переменной pat, - это строки, которые не были продолжены из предыдущих строк. В частности, мы предполагаем, что строки, начинающиеся с цифр, запятой, цифр и запятой, не продолжаются с предыдущей строки. Пересмотреть pat соответствующим образом, если это предположение не выполняется.

# L <- readLines("myfile.csv")
L <- readLines(textConnection(Lines))
# pat <- "^\\S"  # this pattern worked for original input shown in question
pat <- "^\\d+,\\d+,"
L2 <- lapply(split(L, cumsum(grepl(pat, L))), function(x) {
  x <- gsub('"', '""', x)
  x[1] <- sub('^(.*?,.*?,)', '\\1"', x[1])
  x[length(x)] <- paste0(x[length(x)], '"')
  x
})
DF <- read.csv(text = unname(unlist(L2)))
dim(DF)
## [1] 3 3

Примечание

Lines <- 'id,age,note
241,18,I am handsome,I am "18".
242,19, <ul>
    <li>
        <strong>I like music</strong><br />
        Talor swift:I kike Talor,I like her concert{smile}.<br />
        Beyonce:I have 3 albums.</li>
    <ul>
243,17,<I write something sn2370292kl@$^&,hahhaha'
...