Python
api
bioinformatics

PythonでNCBIのAPIから文献情報を取得してみた

前回記事では、PubMedの検索結果のWebページをBeautifulSoupでパースして解析しました(邪道ですが、、、)。今回はNCBIのAPIを使って、以下に挑戦してみました。


  1. 特定の用語に関して、年ごとの検索ヒット数の変化を調べる

  2. ヒットした文献の情報をまとめて取得してリスト化する

PubMed情報を取得できるPythonパッケージとしてBiopythonがありますが、今回は一般的なAPIの取り扱いの練習のために自前で実装してみることにしました。


実行環境


  • MacOS Sierra

  • Xcode 9.2

  • Python 3.6.1

  • requests 2.14.2

  • matplotlib 2.0.2

  • pandas 0.20.1

  • jupyter 1.0.0


ソースコード

PubMedクラスの関数として、以下の2つを用意しました。


  • クエリから検索ヒット件数とidのリストを返すsearch関数

  • idのリストから、論文の詳細情報を取得するget_article_info関数

ソースコード(折りたたみ)

%matplotlib inline

import matplotlib.pyplot as plt
import requests
import time
import pandas as pd
from collections import OrderedDict

class PubMed:
def __init__(self):
self.baseURL = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/"

def search(self,*terms):
terms = "+AND+".join(list(terms))
query = f"db=pubmed&term={terms}"
dataFormat = "json"

search_command = "esearch.fcgi"
self.searchURI = f"{self.baseURL}{search_command}?{query}&retmode={dataFormat}"
result = requests.get(self.searchURI)
print(f"{result}\n")

data = result.json()
self.count = data["esearchresult"]["count"]
self.id_list = data["esearchresult"]["idlist"]

time.sleep(2) #アクセスしすぎないように配慮

def get_article_info(self):
summary_command = "esummary.fcgi"
pubmedURL = "https://www.ncbi.nlm.nih.gov/pubmed/"
key_list = ['source','volume','issue','pages']
new_key_list = ['journal','volume','issue','pages']

self.result_list = []

for n,id in enumerate(self.id_list):
query = f"db=pubmed&id={id}"
dataFormat = "json"
result = requests.get(f"{self.baseURL}{summary_command}?{query}&retmode={dataFormat}")
print(f"{n}:{id}:{result}\n")
data = result.json()

result_dic = OrderedDict()

result_dic['title'] = data['result'][id]['title']

author_list = []
for author in data['result'][id]['authors']:
author_list.append(author['name'])
result_dic['all_authors'] = ", ".join(author_list)

publication_date = data['result'][id]['pubdate']
result_dic['year'] = publication_date.split(" ")[0]

for key,new_key in zip(key_list,new_key_list):
result_dic[new_key] = data['result'][id][key]

result_dic['link'] = f"{pubmedURL}{id}"

self.result_list.append(result_dic)

time.sleep(2) #アクセスしすぎないように配慮



結果


1. 特定の用語に関して、年ごとの検索ヒット数の変化を調べる

"rna-seq"という用語に対し、2004年から2018年までの変化を調べてグラフ化してみました。APIで出版年を指定するタグは[DP]だそうです。

pubmed = PubMed()

hit_count = {}
for year in range(2004,2019):
pubmed.search("rna-seq",f"{year}[DP]")
hit_count[year] = int(pubmed.count)

うまくいくと、<Response [200]>というメッセージが出るようになっています。HTTPのレスポンス状態コードについてはこちらを参照してください。

hit_countをPandasのDataFrameに変換します。

df = pd.DataFrame(hit_count,index=["count"]).T

df

長いため結果のテーブルは折りたたんでいます。




count




2004
0


2005
0


2006
0


2007
0


2008
6


2009
33


2010
156


2011
359


2012
631


2013
1127


2014
1723


2015
2322


2016
2809


2017
3583


2018
3072


Matplotlibでグラフ化した結果がこちら。

plt.plot(df)

plt.xlabel("Year")
plt.ylabel("Hit count")
plt.show()

20180930_rna-seq_hit_count.png

2008年にはじめの報告があり、その後順調に報告数が増加していることがわかります。

近年はやや減少傾向にありますが、理由はよくわかりません。現状、誰でも実施可能なポピュラーな手法になっているため、わざわざ明記しない報告が増えてきた可能性はあります。

[9/30 22:37追記] 先程気づいたのですが、2018年のみ9ヶ月分の集計ですので、最終的には2017年を超える可能性が高いですね。お詫びして訂正いたします。


2. ヒットした文献の情報をまとめて取得してリスト化する

2008年でヒットした、6件の文献情報を取得してみます。

pubmed = PubMed()

pubmed.search("rna-seq","2008[DP]")

print(pubmed.id_list) #取得したidのリスト
#['19087247', '18599741', '18550803', '18516045', '18488015', '18451266']

pubmed.get_article_info() #全てのidの文献情報取得

こちらも実行すると番号:id:<Response [200]>といった、HTTPレスポンス状態コードが返ってくるようにしました。

文献情報はpubmed.result_listに入っています。(折りたたみ)

import pprint

pprint.pprint(pubmed.result_list[-1])

#OrderedDict([('title',
# 'The transcriptional landscape of the yeast genome defined by '
# 'RNA sequencing.'),
# ('all_authors',
# 'Nagalakshmi U, Wang Z, Waern K, Shou C, Raha D, Gerstein M, '
# 'Snyder M'),
# ('year', '2008'),
# ('journal', 'Science'),
# ('volume', '320'),
# ('issue', '5881'),
# ('pages', '1344-9'),
# ('link', 'https://www.ncbi.nlm.nih.gov/pubmed/18451266')])


Pandasデータフレームで見るとこんな感じ。

df_paper = pd.DataFrame(pubmed.result_list[-1],index=["details"]).T

df_paper




details




title
The transcriptional landscape of the yeast gen...


all_authors
Nagalakshmi U, Wang Z, Waern K, Shou C, Raha D...


year
2008


journal
Science


volume
320


issue
5881


pages
1344-9


link
https://www.ncbi.nlm.nih.gov/pubmed/18451266

この論文が"RNA-Seq"という単語を使った、PubMed上で見られる一番最初の報告であると思われます。なんとなく感慨深いですね。