読者です 読者をやめる 読者になる 読者になる

まだ厨二病

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

🌴{rvest}を使って植物の学名をYListから取得する

rvest vegan flora ecological research

一人Rアドベントカレンダーの3日目。何日まで続くかわからないが、@dichika さんを見習って続ける。

今日は仕事の話だ。植物生態学、特に群集データを扱う時のtipsについて書いてみたい。

DSC_8397

群集を対象にした調査を行った場合、1種だけが出現した、ということは稀であり、群集内に生育するさまざまな種をデータとして扱う必要がある。その際、種名データは和名で記載されているものを学名にして、さらに単純化のために属名と種小名からなる記号として扱うことがしばしばある

この時の和名を学名に直す作業を、図鑑を参照しながらちまちまやると時間がかかるし、打ち間違えも発生しやすい(学名は長い)。特に30種とかになると辛い。そのため以前は「BG Plants 和名−学名インデックス(通称YList)」(http://ylist.info) が提供しているcsvファイルから、和名と種名(学名)のマッチングで対応していた。ていた。

植物和名ー学名インデックス YList」(略称:YList)は、「施設に保存されている研究用植物のデータベース」(BG Plants)で用いられる植物名、特に、日本産植物の和名と学名に関する詳細情報の整備を目的として、2003年に米倉浩司(東北大学)と梶田忠(東京大学〔現・千葉大学〕)を中心に作成されたものです。

しかし2015年7月にサーバー移行をしたためか、現在ではファイルを利用することができなくなっている。

「うーむ困ったナ」ってなったのだけど、そういえば「俺にはRがあるじゃないか!」ということで {rvest} を使って和名から対応する標準の学名を取得してみたい。そして、得られた学名をのちの解析で扱いやすいようにするための手順を説明する。

🌴 YListからの学名情報の取得

使用するパッケージを読み込む。 {vegan} は植物生態学をやっている人には超有名なパッケージだ。他、 {flora}パッケージは学名の文字列をよしなにするために利用する。

library(rvest)
library(vegan)
library(flora)
library(tidyr)
library(dplyr)

さて実際にどうするかというと、Ylistの検索機能(http://ylist.info/ylist_simple_search.html)を利用させてもらう。任意の科名、種名、別名、ノートに含まれる検索語を拾ってきてくれるので、ここに自分の扱いたい和名を送れば良い。

まずはYlistへのセッションを確立する。この時の返り値、特にStatusが200になっているので正常にアクセスできていることがわかる。

(session <- html_session("http://ylist.info/ylist_simple_search.html"))
## <session> http://ylist.info/ylist_simple_search.html
##   Status: 200
##   Type:   text/html
##   Size:   3225

次に検索フォームに送りたい和名の文字列を用意し、表示される検索結果のページから取得したいHTMLの部分をxpathで指定する。次のコードの実行結果を以下に示す(先頭の3つのみ表示)。

# アカガシについての学名を取得する
form <- html_form(session)[[1]] %>% set_values("any_field" = "アカガシ")

submit_form(session, form) %>% 
  html_nodes(xpath = "//*[@id='content']/span/span/a") %>% 
  html_text() %>% {
    df_res <<- .
    head(., 3)
  }
## [1] "Quercus acuta Thunb.  アカガシ 標準"                              
## [2] "Quercus acuta Thunb.  var. yanagitae Makino  アカガシ synonym"    
## [3] "Quercus acuta Thunb.  var. megaphylla (Hayashi)  アカガシ synonym"

きちんと取得できている。しかしこのままでは利用しにくいので、取得した結果に処理を加えて次のようにする。

df_res %<>% data_frame(Species = .) %>% 
  dplyr::filter(grepl("標準", Species)) %>% 
  dplyr::mutate(Species = gsub("[[:space:]]標準", "", Species)) %>% 
  tidyr::extract(col = Species, into = c("Species", "Jp.Species"),
                regex = "([[:print:]]+)[[:space:]]([[:print:]]+)")

df_res %>% kable(formar = "markdown")
Species Jp.Species
Quercus acuta Thunb. アカガシ
Quercus acuta Thunb. f. acutiformis (Nakai) H.Ohashi ヒロハアカガシ
Quercus acuta Thunb. f. lanceolata Hatus. ヤナギアカガシ
Quercus morii Hayata タイワンアカガシ
Quercus x yokohamensis (Makino) Makino ex H.Ohba イズアカガシ

順を追って説明すると、まず先ほどの結果をデータフレームとして格納し、そこからsynonimではない、「標準」学名学名を抽出し、学名と和名の列に分離させた。というものである。

ただこれだと、「アカガシ」とつく他の種も該当してしまったり、「ブナ」の場合にはブナ科の種が含まれてしまうので次のようにする。

df_res %>% dplyr::filter(Jp.Species == "アカガシ")
## Source: local data frame [1 x 2]
## 
##                  Species Jp.Species
##                    (chr)      (chr)
## 1 Quercus acuta Thunb.    アカガシ

これを関数化して使いやすくする。query引数を持つylist_names()という関数を書いてみた。

ylist_names(query = "ブナ")
## Source: local data frame [1 x 2]
## 
##                 Species Jp.Species
##                   (chr)      (chr)
## 1 Fagus crenata Blume        ブナ

Ylistの良いところの一つは、和名の別名、いわゆる標準和名でない和名を入れても標準和名に対応させた結果を返してくれるところだ。なので、標準和名ではないムシカリ(オオカメノキの別名)を入れてもオオカメノキ(レンプクソウ科)が返ってくる仕様にした。またlapply()と組み合わせることで複数の種をベクトル形式で与えて一気に検索できる。

species <- c("アカガシ", "ブナ", "イヌガシ", "ムシカリ")

lapply(species, ylist_names) %>% 
  bind_rows() %>% {
    df_res <<- .
    kable(., format = "markdown")
  }
Species Jp.Species
Quercus acuta Thunb. アカガシ
Fagus crenata Blume ブナ
Neolitsea aciculata (Blume) Koidz. イヌガシ
Viburnum furcatum Blume ex Maxim. オオカメノキ

lapply()の関数の使い方に関しては、Hadleyの「Advanced R」で詳しい説明があるっぽい。翻訳も出るらしいので気になる方は一読することをお勧めする。

🎍 学名データを扱いやすくする

先のままだと、学名に命名者などの情報が含まれていて、無駄といえば無駄である。というわけで、ここで {flora}の関数を利用する。{flora}には学名から命名者の情報を削除するremove.authors()という便利な関数がある。次のように使う。

df_res %<>% rowwise() %>% 
    dplyr::mutate(Species = gsub("[[:space:]]$", "", Species)) %>% 
    dplyr::mutate(Species = flora::remove.authors(Species)) %>% 
    ungroup()

df_res$Species
## [1] "Quercus acuta"       "Fagus crenata"       "Neolitsea aciculata" "Viburnum furcatum"

さて次は、この4種について略称を与えてみよう。多種データを扱う場合、学名を利用すると長いので、属名のみにしたり、属名と種小名の頭文字をとってくる、というようなことが行われる。これも手動でやると間違いがあったり、種が追加されると重複してしまう可能性があるので、Rに任せてしまう。ここでは {vegan}make.cepnames()を用いて種名の略称を生成する。また標準関数のabbreviate()を利用しても良い。

df_res %$% make.cepnames(Species)
## [1] "Queracut" "Fagucren" "Neolacic" "Vibufurc"
df_res %$% abbreviate(Species, 2, strict = TRUE)
##       Quercus acuta       Fagus crenata Neolitsea aciculata 
##                "Qa"                "Fc"                "Na" 
##   Viburnum furcatum 
##                "Vf"

もうちょっと改良するべきところはあるだろうが、とりあえずこれで多種データを扱う際には機会があった時に捗る。

💻 実行環境

devtools::session_info() %>% {
  print(.$platform)
  .$packages %>% dplyr::filter(`*` == "*") %>% kable(format = "markdown")
}
##  setting  value                       
##  version  R version 3.2.2 (2015-08-14)
##  system   x86_64, darwin13.4.0        
##  ui       X11                         
##  language En                          
##  collate  en_US.UTF-8                 
##  tz       Asia/Tokyo                  
##  date     2015-12-03
package * version date source
dplyr * 0.4.3.9000 2015-10-28 Github (<hadley/dplyr@52d10f6>)
flora * 0.2.4 2015-03-20 CRAN (R 3.1.3)
ggplot2 * 1.0.1.9003 2015-10-17 Github (<hadley/ggplot2@864d64f>)
knitr * 1.11.8 2015-10-19 Github (<yihui/knitr@a1b235d>)
lattice * 0.20-33 2015-07-14 CRAN (R 3.2.2)
magrittr * 1.5 2015-07-28 Github (<smbache/magrittr@effbadc>)
permute * 0.8-4 2015-05-19 CRAN (R 3.1.3)
pipeR * 0.6.0.6 2015-07-08 CRAN (R 3.2.0)
remoji * 0.1.0 2015-11-19 Github (<richfitz/remoji@dc00779>)
rvest * 0.3.1 2015-11-11 CRAN (R 3.2.2)
tidyr * 0.3.1 2015-09-10 CRAN (R 3.2.0)
vegan * 2.3-2 2015-11-19 CRAN (R 3.2.2)
xml2 * 0.1.2 2015-09-01 CRAN (R 3.2.0)

🔖 出典

このページの学名データは「BG Plants 和名−学名インデックス」から得た。

米倉浩司・梶田忠 (2003-) 「BG Plants 和名−学名インデックス」(YList),http://ylist.info( 2015年12月3日).

上述したコードの利用に関しては、アクセス過多などのYListへ迷惑のかからない範囲内での利用に制限してほしい。

広告を非表示にする