🐮

RによるPubMedの検索結果の取得

2022/06/11に公開

はじめに

Rを用いて、PubMedの検索結果をCSVファイルとして出力する流れをまとめました。

最終的に作りたいCSVファイルは以下のような形式です。(ここではPMID、Title、Abstract、Yearをもってきていますがその他の情報も取得可能です)

No PMID Title Abstract Year
1 99999999 xxx xxx yyyy
2 99999999 xxx xxx yyyy

easyPubMedというパッケージを利用していきます。またPubMedでの検索式の作り方については扱いません。検索式の作り方については、「膨大な医学論文から最適な情報に最短でたどり着くテクニック」などが参考になります。

【参考文献】

目次

  • Package
  • RによるPubMedの検索
    • easyPubmMedで検索結果を取得
    • 得られた結果をCSVに出力
  • ブラウザでの検索結果と一致しない問題と対処法
    • ブラウザで検索結果のPMIDを取得する
    • 結果が不一致なPMIDを抽出する
    • fetch_pubmed_data_by_PMID
  • まとめ
    • (メモ)今後、追加する可能性のある内容

Package

利用するPackageは以下の通り。

#package
library(tidyverse)
library(dplyr)
library(easyPubMed)

RによるPubMedの検索

easyPubmMedで検索結果を取得

easyPubmMedを用いて、RからPubMedの検索を行い検索結果を取得します。

まず、queryを作成します。今回は、"Statistics in medicine"というジャーナルに掲載されていて、"propensity score"がタイトルもしくはアブストラクトに含まれている論文を取得することを考えています。

引数にqueryを入れてget_pubmed_idsを行います。次に、fetch_pubmed_dataを行いますが、retmaxで取得する文献の上限を指定しています。今回は500件を上限にしています。

次に、table_articles_byAuthを行いますが、included_authorsで取得する著者を指定できデフォルトでは全著者を取得するため同一の論文で複数行の結果が返されます。"first"もしくは"last"を指定することで始めの1人または最後の1人の著者情報のみを取得するように指定できます。またmax_charsは取得する文字数の上限になります。

# クエリの定義
query <- 
  "((propensity score[Title/Abstract]) AND (Statistics in medicine[Journal]))"

# PubMedから検索結果の取得
pubmed_ids <- get_pubmed_ids(query)

pubmed_data <- fetch_pubmed_data(pubmed_ids, 
                             encoding = "UTF-8",
                             retmax = 500) 

table_articles <- table_articles_byAuth(
                            pubmed_data,
                            included_authors = "last",
                            max_chars = -1,
                            encoding = "UTF-8")

Result <- table_articles

得られた結果をCSVに出力

必要な情報を選択して、CSVファイルとして出力します。

PubMedから取得している情報は、pmid, doi, title, abstract, year, month, day, jabbrv, journal , keywords, mesh, lastname, firstname, address, email になるので、そのうち必要な項目を選択します。今回は、pmid, title, abstract, yearを指定しています。

names(Result)
Result <- Result[,c("pmid","title","abstract","year")]

write.csv(Result, "path/result_easyPubMed.csv",row.names = TRUE)

ブラウザでの検索結果と一致しない問題と対処法

easyPubmMedを用いることで比較的容易にPubMedの検索結果をRでも取得することができますが、検索式によってはブラウザ上で得られる結果とeasyPubMedによる結果が異なることがあります。

easyPubmMedのGithub上でも報告されています。2020年のコメントですが、原因に関するeasyPubMedの作成者のコメントを引用しておきます。

Hello,

Thanks for reporting this issue. I could reproduce your results, and there is no error in the code. The count difference you observed between the PubMed website and easyPubMed is a current known issue.
in May 2020 NCBI rolled out a new version of PubMed (web). The newly released PubMed web service is built on top of a new database, while programmatic access is only supported for the legacy (old) PubMed. This is the main reason for the query count differences. Unfortunately, I cannot do anything about this until NCBI releases a new API... this has was announced but is not available yet (nor it is known when it will be released). Unfortunately, I anticipate that this problem may persist for at least few more months...

Best regards.

出典:https://github.com/dami82/easyPubMed/issues/4

2022年6月時点でも検索式によっては異なる結果が得られることがあります。例えば、上記のissueでも指摘されているように"patience"をqueryにした場合には、一致しませんでした。

Rを用いて上手く解決できる方法が見つけられなかったので、手作業が一部含まれますが現時点での僕なりの対応策を記載します。ただ基本的には1回のみの検索を想定している対処になります。よりよい解決策がありましたら、ご教示ください。

ブラウザで検索結果のPMIDを取得する

PubMedで検索式(Query)を入力して検索結果を得ます。検索結果のPMIDの一覧を取得します。取得するために、検索ボックスの下にある"Save"から"All results"、フォーマットは"PMID"を指定して"Create file"を実行します。

検索結果に該当した論文のPMIDの一覧がテキストファイルで得られると思います。

以下のようなテキストファイルになります。

35673849
35661207
35603766
…

結果が不一致なPMIDを抽出する

先ほど取得したテキストファイルをRに読み込みます。ファイル名はpmid.txtに変更してます。

その後、easyPubMedで得られたtable_articlesとブラウザ上で取得したPMIDを結合します。今回はブラウザ上の結果を最終的な結果とみなし、ブラウザ上の結果にeasyPubMedの結果をleft_joinで結合させています。

今回のqueryでは問題ありませんが、仮に結果が不一致な場合にはtitleが取得されていないことになるので、titleが欠測しているpmidのリストを作成しています。

いくつかの検索式で試した結果、不一致する論文数はせいぜい数十件ほどなのでこれらの文献については、手作業でPMIDからブラウザ上で検索をすることで必要な情報を取得するような対応は可能だと思われます。

pubmed_pmid <- read.table("path/pmid.txt",
                    sep="\r",
                    header=FALSE,
                    fill=TRUE,
                    fileEncoding = "UTF-8")

pubmed_pmid$V1 <- as.character(pubmed_pmid$V1)
colnames(pubmed_pmid) <- "pmid"

table_articles$pmid <- as.character(table_articles$pmid)
Result <- left_join(pubmed_pmid, table_articles, by = "pmid")

# title が NA を抽出
pubmed_pmid_na <-  filter(Result,is.na(title))
pmid_list_na <- pubmed_pmid_na$pmid

fetch_pubmed_data_by_PMID

一応、easyPubMedの作成者が先ほどのissueでfetch_pubmed_data_by_PMIDを作成したと述べているので触れておきますが、あまりうまく機能しません。

fetch_pubmed_data_by_PMIDの詳細は以下のリンクをご確認下さい。コードも以下のサイトから一部変更して引っ張ってきています。https://rdrr.io/github/dami82/easyPubMed/man/fetch_pubmed_data_by_PMID.html

PMIDから論文情報を取得できるということですが、取得される情報がきれいな形で返ってこないのでそのまま使うことはできないです。うまく整形するのはかなりコストがかかりそうなので、単発で検索するのであれば手作業で確認するほうがよさげです。

fetch_pubmed_data_by_PMIDを利用するには、remotes等でGithubからインストールする必要があるので、通常のpackageのインストールしかしていない場合に以下のコードを実行するとエラーがでると思います。

# example
PMIDs <- c("31506076", "31410434", "31299087", "31552170", 
           "31546103", "31518875", "31518741", "31510010",
           "31509964", "31509747", "31506606", "31503007")

pmabs <- fetch_pubmed_data_by_PMID(PMIDs,
                                   format = "abstract", 
                                   encoding = "UTF-8", 
                                   verbose = TRUE)
# length
length(pmabs)

# show an excerpt
substr(pmabs, 1, 299)

まとめ

本記事では、RのeasyPubMedを用いてPubMedの検索結果をCSVファイルとして出力する方法を紹介しました。PubMedの検索結果に対してデータ分析を行いたい場合や、文献のリストを作成する場合にCSVファイルとして取得する程度であればRを使えば簡単に出力できます。

(メモ)今後、追加する可能性のある内容

  • 不一致をうまくプログラムで解決する方法が見つかれば記載するかもしれません

サポートして頂けるとモチベーションに繋がりますのでぜひ宜しくお願いします。データ解析や臨床研究でのご相談があれば、お気軽にTwiiterもしくはメールにてご連絡下さい。

作成者:Masahiro Kondo
作成日:2022/6/11
連絡先:m.kondo1042(at)gmail.com

Discussion