霞と側杖を食らう

ほしいものです。なにかいただけるとしあわせです。[https://www.amazon.jp/hz/wishlist/ls/2EIEFTV4IKSIJ?ref_=wl_share]

{easyPubMed}パッケージの学習記録

 

【学習動機】

PubMedをRで扱えないものかと思ってググってみたら, {easyPubMed}というパッケージがあった. 検索のときに, ある程度キーワードで絞った後, Rでabstractとかの単語検索して自分の探したい文献を見つけ出したり, 情報を洗い出すのに役立つだろうなと思ったので, {easyPubMed}の使い方を学んでいく.

過去の日本語の記事で{easyPubMed}を扱ったものが一件あったが, パッケージのアップデートによって関数や色々変わっていて, そのままでは使えない状態になっている.

www.karada-good.net

そのため, 公式ドキュメントを眺めながら学習していくことにして, その記録を残す.  

https://cran.r-project.org/web/packages/easyPubMed/easyPubMed.pdf

【学習内容】

私はPubMedについて全く詳しくないのでPubMedの説明もここではしない. PubMedの使い方の基本は東大の医学部図書館などが公開している.  

https://www.lib.m.u-tokyo.ac.jp/manual/pubmedmanual.pdf

以下, {easyPubMed}パッケージの使い方を, ドキュメントを見ながら確認していく.

今回の検索の事例として, 最近, 尿路結石が気になるので尿路結石について調べていく. 尿路結石の治療として外から衝撃波で壊すという話を周りの尿路結石経験者が語っていたのを覚えていた. 体外衝撃波結石破砕術というものらしい. ガイドラインによると,  

「30 数年前の内視鏡を用いた体内式結石破砕術(TULとPNL)と,その数年後に導入された体外衝撃波結石破砕術(ESWL)の開発により,腎切石術,腎盂切石術,尿管切石術などの開放手術が激減し,コペルニクス的な転回を遂げたことは広く知られるところである。」とある. そんなわけで, ESWLのメタ解析をしてそうな文献を探し出すことを今回の事例とする.

尿路結石症診療ガイドライン 2013年版 | Mindsガイドラインライブラリ

ライブラリ読み込み.

library(easyPubMed)
library(tidyverse)    #宇宙
library(stringr)    #文字列の処理
library(lubridate)    #時間の計算

尿路結石をMeSHで, とりあえず見てみる. 検索数を見る. get_pubmed_ids()はリストで簡易的な情報が返ってくる.

#尿路結石("Urinary Calculi")
Query1 <- '"urinary calculi"[MeSH]'
pubmedidlist <- get_pubmed_ids(Query1)
pubmedidlist$Count    #ヒット数
## [1] "34458"

体外衝撃波結石破砕術(ESWL : Extracorporeal Shock Wave Lithotripsy)とメタ解析で絞っていく.

Query2 <- '"extracorporeal shock wave lithotripsy"'
Query3 <- 'meta-analysis'
Query <- str_c('(',Query1,Query2,Query3,')')
Query
## [1] "(\"urinary calculi\"[MeSH]\"extracorporeal shock wave lithotripsy\"meta-analysis)"
get_pubmed_ids(Query)$Count
## [1] "28"

28まで絞れたが, 新しめの知見を得たいので10年以内の文献に絞る.

researchdate <- "20190609"    #検索実行日の決定
tenyearsago <- ymd(researchdate) - years(10) + days(3)
tenyearsago <- tenyearsago %>% as.character() %>% str_replace_all("-","/")
researchdate <- ymd(researchdate) %>% as.character() %>% str_replace_all("-","/")
Querytime <- str_c('AND("',tenyearsago,'"[PDat] : "',researchdate, '"[PDat])' )
Query <- Query %>% str_c(Querytime)
pubmedidlist <- get_pubmed_ids(Query)
pubmedidlist$Count
## [1] "20"

day(3)とずらしているのは, PubMedで10年以内のフィルタをかけると, クエリは’AND (“2009/06/12”[PDat] : “2019/06/09”[PDat])’となる. 10年の期間の計算は何をしているのかは正しく理解しているわけではないが, このへん5年だと12日が11日になるところを見ると, おそらく, 365*10(or 5)を単純に引いて+1日しているもので, うるう年のうるう日分だけ前に来ると考えられるので, 以上のような計算を行った.
結果, 20まで絞れた.
次に, fetch_all_pubmed_idf()で, その20個のpubmedidを手に入れて, カンマでつなげてurlを作成すると, 該当pubmedidのurlができる.

pubmedid <- fetch_all_pubmed_ids(pubmedidlist)
pubmedid
##  [1] "29686172" "28068364" "27798945" "26530230" "26383613" "26382788"
##  [7] "26352272" "26211003" "25909212" "25860144" "25681251" "25449204"
## [13] "24919112" "24863324" "24162890" "22592707" "22161396" "21855945"
## [19] "19889063" "19560860"
pubmedidstr <- pubmedid %>% str_c(collapse = ",")
pubmedidstr %>% str_c("https://www.ncbi.nlm.nih.gov/pubmed/", .)
## [1] "https://www.ncbi.nlm.nih.gov/pubmed/29686172,28068364,27798945,26530230,26383613,26382788,26352272,26211003,25909212,25860144,25681251,25449204,24919112,24863324,24162890,22592707,22161396,21855945,19889063,19560860"

www.ncbi.nlm.nih.gov

fetch_pubmed_dataで詳しい情報入手. XMLで返ってくる.

papers <- fetch_pubmed_data(pubmedidlist, encoding = "ASCII")
papers %>% custom_grep("ArticleTitle", "char") %>% length()
## [1] 20
papers %>% custom_grep("Abstract", "char") %>% length()
## [1] 19

custom_grep()はabstractがない文献(本やコメントなど)がNAで入らないので, 上のように件数が上手く合わなくて個人的に使いにくい.
というわけで, ごり押し気味だけど以下の方法で情報を抽出する.
articles_to_list()で各文献の情報がリストで手に入る. そのリストの中身をそれぞれ, article_to_df()でデータフレームで情報(PMID, DOI, article title, article abstract, publication date (year, month, day), journal name (title, abbreviation), keywords, and a set of author-specific info (names, affiliation, email address))が手に入る. max_charsはabstract全文は10000あれば取れるだろうという設定. 著者が複数いると別のオブザベーションとして入るので, ここでは, 欲しい情報の抜き出しには1行目だけ使う.

articlelist <- papers %>% articles_to_list()
narticles <- length(articlelist)
pmid <- numeric(narticles)
year <- numeric(narticles)
title <- character(narticles)
abstract <- character(narticles)

for(i in 1:narticles){
  df <- articlelist[[i]] %>% article_to_df(max_chars = 10000)
  pmid[i] <- df[1,]$pmid %>% as.numeric()
  year[i] <- df[1,]$year %>% as.numeric()
  title[i] <- df[1,]$title
  abstract[i] <- df[1,]$abstract
}

result <- data.frame(
  pmid = pmid,
  year = year,
  title = title,
  abstract = abstract
)

これでidと出版年とタイトルとアブストラクトの情報をもったデータフレームが手に入った.

アブストラクトに, 体内式結石破砕術(TUL, PNL)のどちらかが入ってるの探す.

result %>% mutate(flg_TUL = str_detect(abstract,"TUL"),
                  flg_PNL = str_detect(abstract, "PNL")) %>% 
  filter(flg_TUL==TRUE | flg_PNL) %>% select(-abstract)
##       pmid year
## 1 25449204 2015
##                                                                                                                                                                                       title
## 1 Systematic review and meta-analysis of the clinical effectiveness of shock wave lithotripsy, retrograde intrarenal surgery, and percutaneous nephrolithotomy for lower-pole renal stones.
##   flg_TUL flg_PNL
## 1   FALSE    TRUE

という感じで, それらしいものが一つだけ得られた. (検索のやり方がとても雑だったのと, もっとガイドラインとか読み込んでからやるべきだった, まぁ, だいたい使い方が分かったので今回は, よしとする.)

www.ncbi.nlm.nih.gov

 

【追記 : 2020/02/28】スライド作成しました(未発表).

 

speakerdeck.com

【学習予定】

PubMedの使い方としてはお粗末だったかもしれないが, {easyPubMed}に関してはこんな感じで使える. 今後は未定.