まだ厨二病

RとPyhtonを使ったデータ分析・統計解析らへんの話題をしていくだけ

「Rによるスクレイピング入門」を執筆しました

タイトルの通り、執筆に関わった書籍が出版されたので内容紹介と宣伝です。

Rによるスクレイピング入門

Rによるスクレイピング入門

「Rによるスクレイピング入門」、この本は書名やカバーから想像するに、 Rを使ってウェブ上のデータを取得し、実践テクニックを豊富に示す 、ことが伺えます。ただし本書で扱う内容はそれだけではありません。以下に述べるように、R言語の解説書、モダンなR言語の操作方法、データ処理・可視化について一通り学べるR言語の本、ウェブ技術書としての側面があります。

本書の多様性

本書の書名を見て、「え?Rでスクレイピング?」といった感想を持たれる方がいるかと思います。Rって、統計解析や可視化が得意な言語だったのでは?… もちろんそれらも得意ですが、Rでできることは実に多様です。多くのプログラミング言語スクレイピングを実行するライブラリがあるように(RubyでいうところのNokogiri、PythonのScrapy)、RでもスクレイピングAPI操作のためのパッケージが開発されています。その中から本書では、主にrvest、httrパッケージを使ったR流の手法を紹介しています。

本書の著者の一人、石田基広先生は「Rデータ自由自在」や「新米探偵、データ分析に挑む」など豊富なR本の翻訳・執筆を経験されています。そのためRのインストールから基礎について学ぶことができます。一方で本書ではRのモダンな操作方法やパッケージを積極的に導入しているのが特徴です。パイプ処理、dplyr、ggplot2、purrrといった手法やパッケージを駆使して、取得したデータを効率的に処理する方法が書かれています。

本書で取り扱うデータ収集の事例は、

  • 対象のデータを選ぶ
  • データを取得する
  • データに対して前処理を行う
  • データを可視化する

といった内容をほとんどの章で扱います。この中の前処理と可視化はウェブデータの処理だけでなく、一般的なデータ操作の段階で必要な事項として活用できるでしょう。前処理の苦労は、テキストファイルでもウェブデータやAPI経由で取得したデータでも変わりがありません。言語や環境を変えずに、データの取得から加工、可視化までをRを通して実行できるというのが、スクレイピングAPI操作にRを用いる大きなモチベーションとなります。

またウェブスクレイピングを行ったりウェブAPIを扱うためには、ウェブに関する基礎知識やマナーに加え、専門技術を必要とします。本書は「入門」書として、これらの内容に触れています。XMLXPath、HTTPのステータスコードといったウェブ技術の解説書としても読むことができるでしょう。また、応用としてログインを必要とするウェブサービススクレイピングやブラウザ操作の自動化処理に用いられるSeleniumの技術にも踏み込みます。

ウェブデータの可能性

最後に、本書やスクレイピングAPIに少しでも興味を持っている方に向けたメッセージです。

ウェブデータ(オープンデータ含む)やAPIの活用は、手持ちのデータや分析の幅を広げるのに有効です。e-StatやRESASでは豊富な行政データが提供されています。また、Google Cloud Vision APIMicrosoft Cognitive ServiceのようなAPIを利用することで、簡単に機械学習モデルを取り込むことも可能になります。

著者の一人、湯谷さんが述べていることですが、 “Tidy API are all alike but every messy API is messy in its own way” と、APIの種類に応じて扱い方が異なってきます。本書のAPI活用事例はごく一部ですが、皆さんが興味を持たれたAPIを利用する際に役立つ内容がきちんと書かれているはずです。

本書の内容に沿ってソースコードを実行するのも良いですが、私は、皆さんが興味ある対象のデータやAPIを活用するために本書を読むのが良いと思います。私はこのブログの過去記事にあるように、趣味の延長でスクレイピングAPIについての知識・経験を深めてきましたが、その時は手探りでやっていた部分が多いです。当時このような本があれば…と思うばかりです。皆さんがウェブデータを利用する際、「罠」に陥ってしまわないよう、本書が指南書となることを期待します。

「Rによるスクレイピング入門」は書店、amazon等で絶賛発売中です。またサポートページとしてRコードを公開しています(なるべく本を買ってね!)。

Rによるスクレイピング入門

Rによるスクレイピング入門

是非!

ODBCで取得したデータの文字化けを解決する

ODBCは良い。古事記には書かれていないかもしれないが、ホクソエムがそう言っている(意訳)。

qiita.com

最近になってR用のODBIインターフェイスである{odbc}パッケージがCRANに登録されたので、Rからも心置き無く使うことができるし、 今後ますます人気が出てくると思う。ただ、実際に使ってみるとnon-ASCII文字列では文字化けを起こす状態で残念な感じだった。

それをなんとかする方法。

# ユーザ名やパスワードはダミー
library(DBI)
# .connection_stringの内容を.odbc.iniに適宜書き込んでおくと省略できる
con <- dbConnect(odbc::odbc(), .connection_string = "Driver={MySQL ODBC 5.3 ANSI Driver};Uid=<ユーザ名>;Pwd=<パスワード>;Server=localhost;Port=3306;Database=<データベース>;CharSet=sjis;")
# この状態ではマルチバイト文字が文字化けしている
d <- con %>% dbReadTable("<テーブル>")
name type
1 ????????? place
2 ???? transportation
3 ??? place
4 ?????? place
d %<>% dplyr::mutate_if(is.character, stringi::stri_conv, 
    from = "sjis", to = "UTF-8")
name type
1 東京ディズニーシー place
2 横浜駅 transportation
3 兼六園 place
4 東京ソラマチ place

CharSetの値にsjisを指定し、R側の文字コード変換関数でUTF8にするという方法。{odbc}側で文字コード問題を解決してくれることを願うが、これで少なくとも日本語については文字化けに対処できる。

余談であるが、ODBCについて詳しく知りたい人は こちらの資料 “Database Best Practices”を見ると良い。これは先月行われたRStudio Conf2017での{odbc}パッケージの開発者であるJim Hesterのスライドである。また発表の様子が公開されているので動画と合わせて見ると良いかもしれない

Enjoy!

RMarkdownファイルの中でSQLを実行する際のtips ~knitr language engine

公式ページに書いている内容なのだけど、覚え書き。

RMarkdownファイルでSQLを実行させるという状況があったとき、{DBI}{odbc} といった各種のデータベース接続用パッケージや{dplyr}の接続関数を利用してデータを呼び出しても良いけど、実はチャンクコード内でSQL直書きできるという話。

過去に

uribo.hatenablog.com

を書いたが、こっちの方がより簡単。

まずはデータベースへの接続を行う。

```{r}
library(DBI)
con <- dbConnect(odbc::odbc(), "MySQL")
```

データベースへ接続された状態がconオブジェクトに保存された。このコネクションを利用して、RMarkdown内で生SQLを実行させていく。肝心なのはチャンク内でエンジンをデフォルトのrではなくてsqlにしておくこと。そしてチャンクオプションのconnectionにconオブジェクトを指定することの2点。

```{sql, connection = con, max.print = 10}
SELECT * FROM mtcars
```

出力件数はSQLのLIMITを使っても良いし、チャンクオプションのmax.printで制御しても良い。

```{sql, connection = con, output.var="sql.mtcars"}
SELECT * FROM mtcars
```

のようにoutput.varオプションを使うとSQLで取得したデータをRオブジェクトとして扱えるようになるので便利。一方でRオブジェクトの値をSQLチャンクに渡すことも可能で、その際は以下のようなコードを書く。手順としては、Rオブジェクトを作り、SQLチャンク内でSQLに引き渡すRオブジェクト名の前に?をつけるだけ。

```{r}
limits <- 7
```
```{sql, connection = con}
SELECT * FROM mtcars LIMIT ?limits
```

コネクションを固定する

都度SQLチャンクにconnectionを指定するのも手間なので、接続状態を維持しておきたいという時にはknitr::opts_chunk()の値にコネクションを残しておけば良い。こうしておくことでSQLチャンクでは常にconnectionで参照しているRオブジェクトを対象とするようになるのでconnectionを書く必要がなくなる。

```{r}
library(DBI)
con <- dbConnect(odbc::odbc(), "MySQL")
knitr::opts_chunk$set(connection = "con")
```

ちなみにknitrの言語エンジンでは、SQL以外にも複数の言語が実行できる環境が整っている。

チャンクで言語を指定するのとengineによる指定による違いがわかっていないのだが。ここにあるものの一部はチャンクで使えるみたい

Language engines - Yihui Xie | 谢益辉

Enjoy!