Ошибка при попытке прочитать PDF с помощью readPDF из пакета tm

(Windows 7/R версии 3.0.1)

Ниже команды и полученная ошибка:

> library(tm)
> pdf <- readPDF(PdftotextOptions = "-layout")
> dat <- pdf(elem = list(uri = "17214.pdf"), language="de", id="id1")

Error in file(con, "r") : cannot open the connection
In addition: Warning message:
In file(con, "r") :
  cannot open file 'C:\Users\Raffael\AppData\Local\Temp
    \RtmpS8Uql1\pdfinfo167c2bc159f8': No such file or directory

Как решить эту проблему?


ИЗМЕНИТЬ I

(Как предложено Беном и описано здесь)

Я скачал Xpdf, скопировал 32-битную версию в C:\Program Files (x86)\xpdf32, а 64-битную версию в C:\Program Files\xpdf64.

Переменные среды pdfinfo и pdftotext относятся к соответствующим исполняемым файлам либо 32-разрядным (протестировано с 32-разрядным R), либо к 64-разрядным (проверено с 64-разрядным R).


ИЗМЕНИТЬ II

Одно очень запутанное наблюдение заключается в том, что, начиная с нового сеанса (tm не загружен), только последняя команда вызовет ошибку:

> dat <- pdf(elem = list(uri = "17214.pdf"), language="de", id="id1")

Error in file(con, "r") : cannot open the connection
In addition: Warning message:
In file(con, "r") :
  cannot open file 'C:\Users\Raffael\AppData\Local\Temp\RtmpKi5GnL
     \pdfinfode8283c422f': No such file or directory

Я вообще этого не понимаю, потому что функциональная переменная еще не определена в tm.readPDF. Ниже вы найдете, что функция pdf относится к «естественно» и к тому, что возвращает tm.readPDF:

> pdf

function (elem, language, id) 
{
    meta <- tm:::pdfinfo(elem$uri)
    content <- system2("pdftotext", c(PdftotextOptions, shQuote(elem$uri), 
        "-"), stdout = TRUE)
    PlainTextDocument(content, meta$Author, meta$CreationDate, 
        meta$Subject, meta$Title, id, meta$Creator, language)
}
<environment: 0x0674bd8c>

> library(tm)
> pdf <- readPDF(PdftotextOptions = "-layout")
> pdf

function (elem, language, id) 
{
    meta <- tm:::pdfinfo(elem$uri)
    content <- system2("pdftotext", c(PdftotextOptions, shQuote(elem$uri), 
        "-"), stdout = TRUE)
    PlainTextDocument(content, meta$Author, meta$CreationDate, 
        meta$Subject, meta$Title, id, meta$Creator, language)
}
<environment: 0x0c3d7364>

Видимо разницы нет - тогда зачем вообще использовать readPDF?


ИЗМЕНИТЬ III

Файл в формате pdf находится здесь: C:\Users\Raffael\Documents

> getwd()
[1] "C:/Users/Raffael/Documents"

ИЗМЕНИТЬ IV

Первая инструкция в pdf() - это вызов tm:::pdfinfo() - и там ошибка возникает в первых нескольких строках:

> outfile <- tempfile("pdfinfo")
> on.exit(unlink(outfile))
> status <- system2("pdfinfo", shQuote(normalizePath("C:/Users/Raffael/Documents/17214.pdf")), 
+                   stdout = outfile)
> tags <- c("Title", "Subject", "Keywords", "Author", "Creator", 
+           "Producer", "CreationDate", "ModDate", "Tagged", "Form", 
+           "Pages", "Encrypted", "Page size", "File size", "Optimized", 
+           "PDF version")
> re <- sprintf("^(%s)", paste(sprintf("%-16s", sprintf("%s:", 
+                                                       tags)), collapse = "|"))
> lines <- readLines(outfile, warn = FALSE)
Error in file(con, "r") : cannot open the connection
In addition: Warning message:
In file(con, "r") :
  cannot open file 'C:\Users\Raffael\AppData\Local\Temp\RtmpquRYX6\pdfinfo8d419174450':   No such file or direc

Видимо tempfile() просто не создает файл.

> outfile <- tempfile("pdfinfo")
> outfile
[1] "C:\\Users\\Raffael\\AppData\\Local\\Temp\\RtmpquRYX6\\pdfinfo8d437bd65d9"

Папка C:\Users\Raffael\AppData\Local\Temp\RtmpquRYX6 существует и содержит несколько файлов, но ни один из них не называется pdfinfo8d437bd65d9.


r tm
person Raffael    schedule 31.07.2013    source источник
comment
Вы правильно настроили pdf2txt PATH? Подробнее см. здесь: stat.ethz.ch/pipermail/r -help/2008-ноябрь/180201.html   -  person Ben    schedule 31.07.2013
comment
пожалуйста, взгляните на отредактированный вопрос   -  person Raffael    schedule 01.08.2013


Ответы (1)


Интересно, на моей машине после нового запуска pdf есть функция для преобразования изображения в PDF:

 getAnywhere(pdf)
A single object matching ‘pdf’ was found
It was found in the following places
  package:grDevices
  namespace:grDevices [etc.]

Но вернемся к проблеме чтения PDF-файлов в виде текста: возиться с PATH немного случайно (и раздражает, если вы работаете на нескольких разных компьютерах), поэтому я думаю, что самый простой и безопасный метод — это вызвать pdf2text с помощью system как описывает Тони Брейал.

В вашем случае это будет (обратите внимание на два набора кавычек):

system(paste('"C:/Program Files/xpdf64/pdftotext.exe"', 
             '"C:/Users/Raffael/Documents/17214.pdf"'), wait=FALSE)

Это можно легко расширить с помощью функции *apply или цикла, если у вас много файлов PDF.

person Ben    schedule 31.07.2013
comment
простой обходной путь. почему бы нет. кажется, есть несколько проблем. прежде всего tempfile не создает файл. Я перезаписал его с помощью file.create, а затем столкнулся с дополнительными проблемами. Это не стоит хлопот. - person Raffael; 01.08.2013
comment
Да, извините, это не решает проблемы, которые вы выявили, но это делает работу. - person Ben; 01.08.2013