便利なRパッケージを見つけたのでメモがてら紹介しておきます。以前、Rを使ってPDF上のテキストを取得するパッケージとして{tm}
パッケージを紹介しましたが、同様の機能をもった{pdftools}
は以下の特徴があります。
- PDFがもつ各種の情報やテキストを取得できる
- 日本語も問題なし
- PDFがロックされている場合、パスワードで開ける
- PDFを画像として出力できる
開発者はrOpenSciの一員でもあるJeroen Oomsです。
{tm}
パッケージでは日本語が含まれるPDFを扱う際にはちょっとした工夫が必要でしたが、{pdftools}
では日本語の出力も問題なく行うことができてちょっと感動しました。機能としてPDFの情報を得る、ということとPDFを画像として出力する、というものがあります。
🔰 使用例
CRANに登録されているのでインストールしてきましょう。
# install.packages('pdftools') library(pdftools)
PDFの情報を得る
{pdftools}
パッケージのコアとなるのが、以下で実行する関数です。引数のpdfに指定したパスのPDFに対して該当する処理を実行します。
# PDFのパスを用意しておく。 # 例として、{zoo}パッケージに付属のPDFを用いる path <- system.file("doc/zoo.pdf", package = "zoo")
pdf_info()
では、PDFがもつ情報を取得します。ページ数や保存された日時やメタ情報などがわかります。
res.info <- pdf_info(pdf = path) # 取得した要素 res.info %>% names()
## [1] "version" "pages" "encrypted" "linearized" "keys"
## [6] "created" "modified" "metadata" "locked" "attachments"
## [11] "layout"
res.info$pages
## [1] 29
res.info$created
## [1] "2015-03-16 14:27:01 JST"
res.info$keys$Creator
## [1] "David M. Jones"
テキストマイニングなどで利用できそうなテキスト抽出の関数としてpdf_text()
があります。この関数では、PDF内のテキストを文字列として返します。ページごとに一つの要素にまとまっているのが特徴です。
res <- pdf_text(path) res[1] %>% { nchar(.) %>% print() strtrim(., 300) }
## [1] 3174
## [1] " zoo: An S3 Class and Methods for Indexed Totally\n Ordered Observations\n Achim Zeileis Gabor Grothendieck\n Universität Innsbruck GKX Associates Inc.\n "
PDF内で利用されているフォントを確認するpdf_fonts()
関数もあります。該当するフォントがインストールされている場合、フォントファイルのパスを表示してくれるのが便利ですね。
# {formattable}で表示形式を変更 library(formattable) pdf_fonts(path) %>% formattable(list(embedded = formatter("span", style = x ~ style(color = ifelse(x, "green", "red")), x ~ icontext(ifelse(x, "ok", "remove"), ifelse(x, "TRUE", "FALSE")))))
name | type | embedded | file |
---|---|---|---|
GOLQXE+CMB10 | type1c | TRUE | |
OGKCHM+CMBX12 | type1c | TRUE | |
MAFAWY+CMSSBX10 | type1c | TRUE | |
AXINBO+CMR10 | type1c | TRUE | |
MQVSZN+CMBX10 | type1c | TRUE | |
GDRMFP+CMSS10 | type1c | TRUE | |
FDHKEF+CMTI10 | type1c | TRUE | |
LLMLMG+CMTT10 | type1c | TRUE | |
ECIDJB+CMBXSL10 | type1c | TRUE | |
XBTYLL+CMSL10 | type1c | TRUE | |
MUVTSF+CMSSI10 | type1c | TRUE | |
HJMIPE+CMTT12 | type1c | TRUE | |
ZCUJTH+CMSLTT10 | type1c | TRUE | |
ZVTVKO+CMR8 | type1c | TRUE | |
ZVTVKO+CMR6 | type1c | TRUE | |
TZIHOI+CMR9 | type1c | TRUE | |
XFSHQU+CMTT9 | type1c | TRUE | |
Helvetica | type1 | FALSE | /Library/Fonts/Microsoft/Arial.ttf |
Helvetica-Bold | type1 | FALSE | /Library/Fonts/Microsoft/Arial Bold.ttf |
ZapfDingbats | type1 | FALSE | /System/Library/Fonts/ZapfDingbats.ttf |
QAYMJR+CMMI10 | type1c | TRUE | |
ZDZXBN+CMTI9 | type1c | TRUE | |
QKDOVZ+CMSS9 | type1c | TRUE | |
HWQZWS+CMBXTI10 | type1c | TRUE |
pdf_toc()
はPDFの情報から、見出しだけを抽出する関数です。地味に嬉しい気がします。返り値はリストクラスオブジェクトとなっており、適当な処理で目次を再現することができそうです。
res.toc <- pdf_toc(path) res.toc %>% class()
## [1] "list"
library(purrr) # 章だけを抽出 res.toc$children %>% map_chr(c("title"))
## [1] "Introduction" "The class \"zoo\" and its methods"
## [3] "Combining zoo with other packages" "Summary and outlook"
## [5] "Reference card"
# 節はどうする?? # もうちょっと効率的な方法があるはず... res.toc$children[[2]]$children %>% map_chr("title")
## [1] "Creation of \"zoo\" objects"
## [2] "Creation of \"zooreg\" objects"
## [3] "Plotting"
## [4] "Merging and binding"
## [5] "Mathematical operations"
## [6] "Extracting and replacing the data and the index"
## [7] "Coercion to and from \"zoo\""
## [8] "NA handling"
## [9] "Rolling functions"
# 適当に取り出すだけなら... res.toc %>% unlist()
## title
## ""
## children.title
## "Introduction"
## children.title
## "The class \"zoo\" and its methods"
## children.children.title
## "Creation of \"zoo\" objects"
## children.children.title
## "Creation of \"zooreg\" objects"
## children.children.title
## "Plotting"
## children.children.title
## "Merging and binding"
## children.children.title
## "Mathematical operations"
## children.children.title
## "Extracting and replacing the data and the index"
## children.children.title
## "Coercion to and from \"zoo\""
## children.children.title
## "NA handling"
## children.children.title
## "Rolling functions"
## children.title
## "Combining zoo with other packages"
## children.children.title
## "strucchange: Empirical fluctuation processes"
## children.children.title
## "tseries: Historical financial data"
## children.children.title
## "timeDate/fCalendar: Indexes of class \"timeDate\""
## children.children.title
## "The classes \"yearmon\" and \"yearqtr\": Roll your own index"
## children.title
## "Summary and outlook"
## children.title
## "Reference card"
またpdf_attachments()
という関数もありますが、PDFに付属するファイルの情報を取得するものと思われますが、手持ちのファイルではそのようなものがなかったので未検証です。
pdf_attachments(path)
## list()
開くのにパスワードが必要なPDFでは、パスワードを指定する引数opwおよびupwがあるので、そちらにパスワードを渡します。
# 某申請書で埋め込まれていたフォント情報 pdf_fonts("hogehoge.pdf", upw = "piyopiyo") %>% dplyr::mutate(name = iconv(name, from = "cp932", to = "utf8")) %>% # フォント名が文字化けしていたので直してやる formattable(list(embedded = formatter("span", style = x ~ style(color = ifelse(x, "green", "red")), x ~ icontext(ifelse(x, "ok", "remove"), ifelse(x, "TRUE", "FALSE")))))
name | type | embedded | file |
---|---|---|---|
MSゴシック | cid_truetype | FALSE | /Library/Fonts/Microsoft/MS Gothic.ttf |
MS明朝 | cid_truetype | FALSE | /Library/Fonts/Microsoft/MS Gothic.ttf |
@MSゴシック | cid_truetype | FALSE | /Library/Fonts/Microsoft/MS Gothic.ttf |
PDFをビットマップとして出力する
もう一つの機能として、PDFファイルのイメージをビットマップファイルとして出力するpdf_render_page()
関数があります。この関数を利用するにはlibpopplerがインストールされている必要があるようですが、私の環境では何もしない状態で実行できました。出力の拡張子は.png
(png::writePNG()
), .jpg
(jpeg::writeJPEG()
), .webp
(webp::write_webp()
)となります。
library(png) bitmap <- pdf_render_page(path) writePNG(bitmap, "pdf_out.png")
引数でページ数やDPIの指定など細かな調節ができます。
# 高解像度での出力。dpiの初期値は72 bitmap <- pdf_render_page(path, page = 9, dpi = 250) writePNG(bitmap, "pdf_out2.png")
Enjoy 😎
💻 実行環境
package | version | source |
---|---|---|
formattable | 0.1.5 | CRAN (R 3.2.2) |
magrittr | 1.5 | Github (<smbache/magrittr@00a1fe3>) |
pdftools | 0.1 | CRAN (R 3.2.3) |
png | 0.1-7 | CRAN (R 3.1.0) |
purrr | 0.2.1 | CRAN (R 3.2.3) |
remoji | 0.1.0 | Github (<richfitz/remoji@dc00779>) |