RでDeepL APIを使って翻訳する。

# モチベーション
日頃から[DeepL](https://www.deepl.com/ja/home)には大変お世話になっていますが、手動で大量の文章をコピペしていくのはちょっと大変です。そこで、DeepLが提供しているAPIを利用してCUIベースで目的の文章を翻訳してみます。pythonでの使用例はいくつかあったのですが、Rは見当たらなかったのでRで実行してみます。

※[DeepL API](https://www.deepl.com/pro#developer)に登録して認証キーを取得していることを前提にしています。
※本記事はRでDeepL APIを利用するところまでです。最終的にはPMIDから論文要旨の翻訳を取得したいのですが、別の記事にまとめたいと思います。

# 参考
[DeepL API Simulator](https://www.deepl.com/docs-api/simulator/)
[R API Tutorial: Getting Started with APIs in R](https://www.dataquest.io/blog/r-api-tutorial/)

# 環境

```r
sessionInfo()
# R version 3.4.2 (2017-09-28)
# Platform: x86_64-apple-darwin15.6.0 (64-bit)
# Running under: macOS  10.14.1
```

# 方法
### 必要なパッケージの準備
RでAPIを利用するためのhttrパッケージ、JSON形式のデータを扱うためのjsonliteをインストールします。

```r
install.packages(c("httr", "jsonlite"))
library(httr)
library(jsonlite)
```

### リクエストするURLの作成
[DeepL API Simulator](https://www.deepl.com/docs-api/simulator/)では実際に自分の認証キーや翻訳したい文章を入力して、リクエストするURLを確認することができます。私は今までAPIを使用した経験があまりないため、このシミュレーション結果をもとにリクエストするURLを作成していきます。そのためスマートな方法ではないかもしれません。もしより良い方法があれば教えてください。
翻訳する文章は不思議の国のアリスの第1章になります（[Alice's Adventures in Wonderland (1907)/Chapter 1](https://en.wikisource.org/wiki/Alice%27s_Adventures_in_Wonderland_(1907)/Chapter_1)）。

```r
rm(list = ls())

apiURL <- "https://api.deepl.com/v2/translate"
auth_key <- "YOUR_AUTH_KEY" #認証キー
text <- "ALICE was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, “and what is the use of a book,” thought Alice, “without pictures or conversations?”
So she was considering in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid) whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her."

#リクエストするURL用に空白などを置換します。このあたり専用のパッケージで変換できそうなのですが。。。
#->hzkm様にご紹介頂いた「URLencode()」で対応可能でした！
#text4api <- gsub(pattern = " ", replacement = "%20", text) #空白を%20で置換
#text4api <- gsub(pattern = "\n", replacement = "%0A", text4api) #改行を%0Aで置換
source_lang <- "source_lang=en" #英語から
target_lang <- "target_lang=ja" #日本語に変換

#リクエストするURLの作成
target_url <- paste(apiURL, "?", auth_key, "&text=", URLencode(text), "&", target_lang, 
                    "&", source_lang, "&", "tag_handling=0", sep = "")
```

### 翻訳結果の取得
httrパッケージのGET関数を使ってレスポンスを取得します。「Status: 200」から正常に取得できたと分かります。作成するURLに不具合があるとStatusは400や403になります（[APIのHTTPステータスコードについて考える](https://developer.ntt.com/ja/blog/6f5aa9be-7135-496a-9019-208a1562ad66)）。また、「Content-Type: application/json」からJSON形式であることが分かります。

```r
responce <- GET(target_url)
responce
# Date: 2020-07-04 11:29
# Status: 200
# Content-Type: application/json
# Size: 625 B
```

翻訳結果はcontentに格納されていますが、raw型となっておりそのままでは結果を確認することができません。rawToChar関数で文字列に変換します。

```r
responce$content
# [1] 7b 22 74 72 61 6e 73 6c 61 74 69 6f 6e 73 22 3a 5b 7b 22 64 65 74 65
class(responce$content)
# [1] "raw"
rawToChar(responce$content)
# [1] "{\"translations\":[{\"detected_source_language\":\"EN\",\"text\":\"アリスは、土手の上で妹のそばに座っていること、何もしないことにとても疲れ始めていました。一度や二度、妹が読んでいる本を覗き込んだことがありましたが、そこには絵も会話もありませんでした。\\nそこでアリスは自分の心の中で（暑い日のせいでとても眠くて愚かな気分になっていたので、できる限り）デイジーチェーンを作る楽しみが、起きてデイジーを摘む手間に見合うものかどうかを考えていました。\"}]}"
```
rawToChar(responce$content)はJSON形式なのでjsonliteパッケージのfromJSON関数で変換します。

```r
translated <- jsonlite::fromJSON(rawToChar(responce$content))
translated
# $translations
# detected_source_language
# 1                       EN
# text
# 1 アリスは、土手の上で妹のそばに座っていること、何もしないことにとても疲れ始めていました。一度や二度、妹が読んでいる本を覗き込んだことがありましたが、そこには絵も会話もありませんでした。\nそこでアリスは自分の心の中で（暑い日のせいでとても眠くて愚かな気分になっていたので、できる限り）デイジーチェーンを作る楽しみが、起きてデイジーを摘む手間に見合うものかどうかを考えていました。
```
変換後はリスト形式になります。翻訳結果はリスト内データフレームの$textに格納されています。

```r
cat(as.character(translated$translations[2]))
# アリスは、土手の上で妹のそばに座っていること、何もしないことにとても疲れ始めていました。一度や二度、妹が読んでいる本を覗き込んだことがありましたが、そこには絵も会話もありませんでした。
# そこでアリスは自分の心の中で（暑い日のせいでとても眠くて愚かな気分になっていたので、できる限り）デイジーチェーンを作る楽しみが、起きてデイジーを摘む手間に見合うものかどうかを考えていました。
```

# 結果
翻訳前
>ALICE was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, “and what is the use of a book,” thought Alice, “without pictures or conversations?”
So she was considering in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid) whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her.

翻訳後
>アリスは、土手の上で妹のそばに座っていること、何もしないことにとても疲れ始めていました。一度や二度、妹が読んでいる本を覗き込んだことがありましたが、そこには絵も会話もありませんでした。
そこでアリスは自分の心の中で（暑い日のせいでとても眠くて愚かな気分になっていたので、できる限り）デイジーチェーンを作ることの楽しさが、起きてデイジーを摘む手間に見合うかどうかを考えていました。


非常にこなれた訳でスラスラと読めます。

ただ、なぜかアリスの独白（“and what is the use of a book,” thought Alice, “without pictures or conversations?”）とウサギを見かける文（when suddenly a White Rabbit with pink eyes ran close by her.）がすっぽり抜け落ちています。
ブラウザ版でも同じように抜け落ちるのでどうやら仕様のようです。この後に続く文章も同時に入力するとウサギを見かける文は問題なく翻訳されます。