Как экранировать специальные символы в функции read.table в R? - PullRequest
0 голосов
/ 09 марта 2020

Я пытаюсь извлечь фрейм данных в R из словаря произношения Карнега ie Mellon University. Это прекрасно работает для получения фрейма данных:

url <- "http://svn.code.sf.net/p/cmusphinx/code/trunk/cmudict/cmudict-0.7b"
library(RCurl)
answer <- RCurl::getURL(url)
dictionary <- as.vector(unlist(strsplit(answer, "\n")))
dictionary <- gsub("  ", "\t", dictionary)
dictionary.df <- read.table(text = dictionary, header=FALSE, skip =150, sep = "\t")

Но содержимое словаря находится после строки 54, поэтому значение параметра пропуска должно быть «54». Кажется, что специальные символы, содержащиеся в строках с 54 по 150, вызывают следующие ошибки.

Например:

> dictionary.df <- read.table(text = dictionary, header=FALSE, skip =54, sep = "\t")
Error in scan(file = file, what = what, sep = sep, quote = quote, dec = dec,  : 
  line 1 did not have 2 elements


> dictionary.df <- read.table(text = dictionary, header=FALSE, skip =120, sep = "\t")
Warning messages:
1: In scan(file = file, what = what, sep = sep, quote = quote, dec = dec,  :
  Fin de fichier (EOF) dans une chaîne de caractères entre guillements
2: In scan(file = file, what = what, sep = sep, quote = quote, dec = dec,  :
  le nombre d'objets lus n'est pas un multiple du nombre de colonnes

Есть ли быстрый способ избежать этой ошибки, избегая символов?

Большое спасибо за вашу помощь!

Людови c

Ответы [ 3 ]

1 голос
/ 09 марта 2020

fread из пакета data.table здесь уместно.

library(data.table)

dt_dic <- fread(url, skip=56, sep=NULL, header = FALSE, col.names="Item")

dt_dic[, c("Item", "Pronunciation") := tstrsplit(Item, "  ")]
dt_dic
                      Item                            Pronunciation
     1: !EXCLAMATION-POINT EH2 K S K L AH0 M EY1 SH AH0 N P OY2 N T
     2:       "CLOSE-QUOTE                      K L OW1 Z K W OW1 T
     3:      "DOUBLE-QUOTE                  D AH1 B AH0 L K W OW1 T
     4:      "END-OF-QUOTE                  EH1 N D AH0 V K W OW1 T
     5:         "END-QUOTE                        EH1 N D K W OW1 T
    ---                                                            
133850:             {BRACE                                B R EY1 S
133851:        {LEFT-BRACE                      L EH1 F T B R EY1 S
133852:        {OPEN-BRACE                    OW1 P EH0 N B R EY1 S
133853:       }CLOSE-BRACE                      K L OW1 Z B R EY1 S
133854:       }RIGHT-BRACE                        R AY1 T B R EY1 S
1 голос
/ 09 марта 2020

Я думаю, что это проблема х / у.

У вас уже есть данные в памяти в символьном векторе dictionary, и вы хотите превратить их в кадр данных. Вы пытаетесь использовать read.table для этого и застряли, потому что read.table борется с некоторыми специальными символами в векторе. Вместо того, чтобы пытаться найти способ заставить read.table выполнить работу, почему бы просто не разбить строки в двойных пробелах и связать их вместе во фрейм данных?

Когда я скачал файл, заголовок занимает 56, а не 54 строки, поэтому мы отбрасываем их, затем вызываем strsplit в двойных пробелах оставшихся строк, без необходимости сначала преобразовывать их в \t символов. Затем мы используем as.data.frame(do.call("rbind", ...)) в результирующем списке, чтобы получить наш фрейм данных.

Вот репрезекс:

url <- "http://svn.code.sf.net/p/cmusphinx/code/trunk/cmudict/cmudict-0.7b"
answer <- RCurl::getURL(url)
dictionary <- as.vector(unlist(strsplit(answer, "\n")))
dictionary.df <- strsplit(dictionary[-seq(56)], "  ")
dictionary.df <- as.data.frame(do.call("rbind", dictionary.df), stringsAsFactors = FALSE)
names(dictionary.df) <- c("Item", "Pronunciation")
head(dictionary.df)
#>                 Item                            Pronunciation
#> 1 !EXCLAMATION-POINT EH2 K S K L AH0 M EY1 SH AH0 N P OY2 N T
#> 2       "CLOSE-QUOTE                      K L OW1 Z K W OW1 T
#> 3      "DOUBLE-QUOTE                  D AH1 B AH0 L K W OW1 T
#> 4      "END-OF-QUOTE                  EH1 N D AH0 V K W OW1 T
#> 5         "END-QUOTE                        EH1 N D K W OW1 T
#> 6         "IN-QUOTES                        IH1 N K W OW1 T S

Создано в 2020-03-09 Представить пакет (v0.3.0)

0 голосов
/ 10 марта 2020

Я хотел сравнить предложенные решения по времени:

dic.url <- "http://svn.code.sf.net/p/cmusphinx/code/trunk/cmudict/cmudict-0.7b"

function1 <- function(dic.url){
  start_time <- Sys.time()
  library(data.table)
  dic <- fread(dic.url, skip=56, sep=NULL, header = FALSE, col.names="Item")
  dic[, c("Item", "Pronunciation") := tstrsplit(Item, "  ")]
  end_time <- Sys.time()
  time <- end_time - start_time
  print(time)
  return(dic)
  }

function2 <- function(dic.url){
  start_time <- Sys.time()
  answer <- RCurl::getURL(dic.url)
  dic <- as.vector(unlist(strsplit(answer, "\n")))
  dic <- strsplit(dic[-seq(56)], "  ")
  dic <- as.data.frame(do.call("rbind", dic), stringsAsFactors = FALSE)
  names(dic) <- c("Item", "Pronunciation")
  end_time <- Sys.time()
  time <- end_time - start_time
  print(time)
  return(dic)
  }

dic <- function1(dic.url)
dic <- function2(dic.url)

Некоторые показания:

> dic <- function1(dic.url)
Time difference of 2.627239 secs

> dic <- function2(dic.url)
Time difference of 3.394491 secs
...