R: параллельное чтение xml-файлов с помощью xml2, doParallel и foreach

#r #foreach #doparallel #xml2

#r #foreach #doparallel #xml2

Вопрос:

в настоящее время я работаю над небольшим проектом R для чтения некоторой информации из файлов Word. Поскольку это архивированные XML-файлы под капотом, я подумал, что эта задача будет довольно простой с R. Мой скрипт в основном работает, но я хотел увеличить его скорость, поэтому я взглянул на doParallel foreach пакеты и .

 library(foreach)
library(doParallel)

cores <- detectCores()
cl <- makeCluster(cores - 1)
registerDoParallel(cl)


file_list <- list.files(path = "/path/to/word/files", pattern = glob2rx("*.docx"), ignore.case = TRUE, full.names = TRUE, recursive = TRUE)


final <- foreach(
  filename = file_list[1:4], .combine = rbind, .packages = c("stringr", "xml2", "tibble"),
  .verbose = T, .inorder = FALSE
) %dopar% {

  name <- str_extract(filename, "[0-9a-f]{40}")


  # doc <- read_xml(unzip(zipfile = filename,  files = c("word/document.xml")), encoding = "utf-8")


  df <- tibble(
    Name = name,
  )

  df
}

stopCluster(cl)
 

Этот скрипт работает нормально, но если я раскомментирую строку, содержащую read_xml оператор, и запускаю скрипт, я получаю несовместимые ошибки, такие как

Фелер в { : ошибка задачи 1 — «Несоответствие открывающего и завершающего тегов: строка 2 pPrPr и r [76]»

или

Фелер в { : задача 1 выполнена с ошибкой — «Спецификация требует значения для атрибута MERGEFORMAT [41]»

или

Фелер в { : ошибка задачи 1 — «Дополнительный контент в конце документа [5]»

Таким образом, использование пакета xml2 в параллельной среде, похоже, не работает. Переключение с %dopar% на %do% решает проблему, но я теряю ускорение.

Я знаю, что указатели, сгенерированные xml2, недопустимы в разных потоках R, но моя идея заключалась в том, чтобы читать и обрабатывать один docx-файл на поток. Есть идеи, как решить эту проблему?

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

1. Что происходит в unzip ? Физически ли он разархивирует файл word/document.xml из архива и помещает файл в рабочую директорию? В этом случае, если выполняется параллельно, он будет повторно перезаписывать существующий document.xml новым файлом из параллельного архива, в то время как предыдущий процесс все еще пытается его прочитать.