はじめに
科学論文などの文献資料の多くは、通常、PDF形式のファイルで保管されています。
このフォーマットは主に印刷用に設計されているため、検索や索引付けにはあまり適していません。 PDFファイルは、OSやソフトウェアが変わっても、書式が変わらないのが強みですね。
rOpenSciが提供する、pdftoolsパッケージを使えば、 R環境で、PDFファイルから、テキストやメタデータを抽出できるみたいです。
今回、PDFファイルを読み込み、テキスト生成とかをR環境でやってみました。
関連パッケージのインストール
まずは、「pdftools」パッケージとツール群をインストールします。
#関連ページ browseURL("https://github.com/ropensci/pdftools") browseURL("https://cran.r-project.org/web/packages/pdftools/index.html") #pdftoolsのインストール install.packages("pdftools") #事前にセットアップ For MacOSX system("brew install poppler") system("brew install wget") #パッケージ・ロード library(pdftools)
Getting started (1) 英語論文での事例
pdf2textパッケージで、最も重要な関数は、pdf_text
関数で、
pdfのページ数と同じ長さの文字ベクトルを返します。
また、ベクトル内の各文字列は、 そのページ内のプレーンテキストに変換されます。
それでは、
The jsonlite Package: A Practical and Consistent Mapping Between JSON Data and R Objects
のArxiv論文PDFを使って、検証してみます。
#ダウンロード download.file("http://arxiv.org/pdf/1403.2805.pdf", "1403.2805.pdf", mode = "wget") #Check #dir(pattern = ".pdf") #変換 txt <- pdftools::pdf_text("1403.2805.pdf") #1ページ目のテキスト cat(txt[1]) #2ページ目のテキスト cat(txt[2]) #簡単な前処理: 空白と改行記号を消す #1ページ目を抜き出す a <- txt[1] for(n in 1:10){ a <- gsub(" ", " ", a) a <- gsub("\n", " ", a) }
結果として、以下のような、テキストが抽出されました。
#出力 a #[1] " The jsonlite Package: A Practical and Consistent Mapping Between #JSON Data and R Objects Jeroen Ooms arXiv:1403.2805v1 [stat.CO] 12 Mar #2014 UCLA Department of Statistics Abstract A naive realization of JSON data #in R maps JSON arrays to an unnamed list, and JSON objects to a named list. #However, in practice a list is an awkward, inefficient type to store and manipulate #data. Most statistical applications work with (homogeneous) vectors, matrices #or data frames. Therefore JSON packages in R typically define certain special #cases of JSON structures which map to simpler R types. Currently there #......... #書き出し・表示 readr::write_excel_csv(as.data.frame(a), "a.csv", col_names = F) browseURL("./a.csv")
Getting started (2) 日本語資料での事例
英語論文で試しましたが、次に、日本語のPDFファイルではどうかを検証してみます。
「マクマリー 生化学反応機構」という専門書籍の、とあるページで試してみます。
#ダウンロード download.file("http://www.tkd-pbl.com/files/mcmurry_seikagakuhannoukikou_2nd.pdf", "seikagaku_2nd.pdf", mode = "wget") #変換 txtJpn <- pdftools::pdf_text("seikagaku_2nd.pdf") txtJpn #簡単な前処理: 空白と改行記号を消す b <- txtJpn[1] for(n in 1:10){ b <- gsub(" ", "", b) b <- gsub("\n", " ", b) b <- gsub(".", ".", b) b <- gsub(",", ",", b) } b #[1] "生化学と有機化学を相互につなぐ教科書マクマリー生化学反応機構― #ケミカルバイオロジーによる理解―第2版J.McMurry,T.Begley著長野哲雄監 #訳A5判・井上英史,浦野泰照,小島宏建,496ページ鈴木紀行,平野智也訳 #定価:本体5400円+税東京化学同人「生命活動は化学反応によって成り学 #の世界として,頭に詰め込まれてい学問体系の相互的な理解が進むように工立 #っている.だから有機化学を学ぶことく.一方で生化学の教科書では,生体内夫 #されており,深い学びへと誘うアクは,生命を理解することにつながるのでひ #き起こされる物質変換の様子が連続ティブラーニングが自然と達成できる教だ」私が #.... #書き出し・表示 readr::write_excel_csv(as.data.frame(b), "b.csv", col_names = F) browseURL("./b.csv")
実行時に、PDF error: Invalid Font Weight
というエラーが出ていますが、特に結果に問題なさそうです。
他のユーティリティについて
pdf_toc関数で目次(ToC)を取得・表示する
加えて、このパッケージには、PDFファイルから他のデータを抽出するためのユーティリティがいくつか用意されています。
pdf_toc
関数は、目次(ToC)を取得・表示します。
つまり、PDFリーダーが通常、左側のメニューパネルに表示するセクションヘッダーを意味します。
JSON形式だと、うまく表示されるらしいです。
# 目次の取得 toc <- pdftools::pdf_toc("1403.2805.pdf") toc #$title #[1] "" # #$children #$children[[1]] #$children[[1]]$title #[1] "1 Introduction" # #$children[[1]]$children #$children[[1]]$children[[1]] #$children[[1]]$children[[1]]$title #[1] "1.1 Parsing and type safety" #... #JSON形式での表示 jsonlite::toJSON(toc, auto_unbox = TRUE, pretty = TRUE) #{ # "title": "", # "children": [ # { # "title": "1 Introduction", # "children": [ # { # "title": "1.1 Parsing and type safety", # "children": [] # }, # { # "title": "1.2 Reference implementation: the jsonlite package", # "children": [] # }, # { # "title": "1.3 Class-based versus type-based encoding", # "children": [] # }, #....
メタデータに関する情報
また、pdf_info関数などを使えば、フォントや添付ファイル、作者や作成日、タグなどのメタデータに関する情報を取得できます。
# Author, version, etc info <- pdftools::pdf_info("1403.2805.pdf") info #$version #[1] "1.4" #$pages #[1] 29 #$encrypted #[1] FALSE #$linearized #[1] FALSE #$keys #$keys$Producer #[1] "dvips + GPL Ghostscript GIT PRERELEASE 9.08" #...... # Table with fonts fonts <- pdftools::pdf_fonts("1403.2805.pdf") fonts # name type embedded file #1 Times-Roman type1 FALSE /System/Library/Fonts/Times.ttc #2 UWJIZQ+CMTT10 type1c TRUE #3 OYDUEZ+CMR10 type1c TRUE #4 EBLJKS+CMTI10 type1c TRUE #5 APBPVY+CMBX12 type1c TRUE #6 FBFBNT+CMTI9 type1c TRUE #...... #Table with attachments files <- pdftools::pdf_attachments("1403.2805.pdf") files #list() #Table with data Dat <- pdftools::pdf_data("1403.2805.pdf") head(Dat[[1]]) # width height x y space text #1 27 15 92 115 TRUE The #2 71 14 124 117 TRUE jsonlite #3 59 15 200 115 TRUE Package: #4 11 15 266 115 TRUE A #5 61 15 284 115 TRUE Practical #6 25 15 350 115 TRUE and
また、PDFファイルをビットマップ配列にレンダリングする機能もあります*1。
R環境では、pdf_render_page
関数を使って、PDFの1ページをビットマップにレンダリングできます。
# pdf から bitmap へのレンダー bitmap <- pdftools::pdf_render_page("1403.2805.pdf", page = 1) # bitmap 画像の保存 png::writePNG(bitmap, "page.png", dpi = 100) jpeg::writeJPEG(bitmap, "page.jpg", quality = 0.7, bg = "white") #install.packages("webp"); library(webp) #webp::write_webp(bitmap, "page.webp") #ファイルを開く browseURL("./page.png") browseURL("./page.jpg")
まとめ
pdftoolsを使って、PDFファイルのテキスト変換を一通りやってみました。
結構、便利そうに思いますね。。。
*1:popplerライブラリの事前インストールが必要です