Systematic ReviewのWork Flowまとめ

はじめまして、フリーランスのますみです!

一人一人が自立・共存・革新している「クリエイターエコノミー」を創る。』というビジョンに向けて活動しています。

最近、コロナ・パンデミックの影響でデータが取れないこともあり、システマティックレビューをする機会がありました。その際、色々なシステマティックレビューを参考にしたため、そこで得た知見をまとめたいと思います。

※ 絶対的に正しい手法を保証するものではないため、参考程度にご覧ください。

全体の流れ

  1. Objective Decision(目的の決定)
  2. Method Decision(手法を決定)
  3. “Search Word” Decision(検索用語の決定)
  4. Fetch “Search Data”(検索結果の取得)
  5. Duplicate Removal(重複文献の削除)
  6. Abstract Screening(抄録からスクリーニング)
  7. Full-Text Article Screening(論文全体からスクリーニング)
  8. Flow Diagram Visualization(スクリーニング工程の図示化)
  9. Analysis(スクリーニングした論文から解析)
  10. Publication (アウトプット)

各フローの詳細

1. Objective Decision(目的の決定)

まずは目的を決めましょう。 決める時のポイントとして「メタな解析を行うことの利点」を考えるといいかもしれません。

  • 検出力が低い研究だから、メタな解析により検出力を上げる。
  • デファクトスタンダードを知りたい。
  • 研究を始める前に、先行研究の効果量(Effect Size)を定量化したい。

2. Method Decision(手法を決定)

次に、どのような流れでレビューをするか決めましょう。また、レビューの方法だけではなく、スクリーニングした論文からどのような手法で、結果を算出するかなども先に決めておくといいでしょう。

先行研究などでは、PRISMA Guidelineに沿っている研究が多いため、本記事ではPRISMAに準拠して、進めていきます。

PRISMAとは?

Preferred Reporting Items for Systematic Reviews and Meta-Analysesの略です。

簡単に言うと、システマティックレビュー(Systematic Review)やメタアナリシス(Meta-Analysis)の質を担保するために定めたチェックリスト(ガイドライン)になります。

論文の作者がPRISMAのチェックリストを記入して、Publishすることで、私たちのようにシステマティックレビュー(Systematic Review)やメタアナリシス(Meta-Analysis)を行う人たちがスクリーニングを正確に行うことができます。また、もしもチェックリストが論文に掲載されていない場合は、このチェックリストに沿って、分析をすることができます。

また、PRISMAのFlowとしては、Identification => Screening => Eligibility => Includedという流れで論文を絞っていきます。

【参考】PRISMA公式サイト

3. “Search Word” Decision(検索用語の決定)

続いて、検索用語を決めましょう。 おそらくここが一番悩みどころだと思われますが、以下のようなポイントに気をつけて、決めるといいかもしれません。

  • 先行研究で、用いられている検索用語を引用する。
  • 同義語 / 類義語を含める(”Brain-Machine Interface” OR “Brain-Computer Interface”)。
  • 略語を含める(”Magnetic Resonance Imaging” OR “MRI”)。
  • ワイルドカードを用いる(”gamification” OR “gamified” => “gamif*”)。

これ以降は、例として「日本でのコロナウイルス研究の実態を調べる」ために(”COVID-19” AND “Japan”)という検索用語を用いていきたいと思います。

4. Fetch “Search Data”(検索結果の取得)

検索用語が決まったら、実際に検索をして、ヒットした論文情報をダウンロードしましょう。検索する媒体は論文によって、異なりますが、ここでは、Web Of Science、Scopus、Pubmedの3つのダウンロード方法について紹介します。

A. Web of Science

Sys-Rev-SC1
Sys-Rev-SC2
Sys-Rev-SC3
Sys-Rev-SC4
Sys-Rev-SC5
Sys-Rev-SC6

B. Scopus

Sys-Rev-SC7
Sys-Rev-SC8
Sys-Rev-SC9
Sys-Rev-SC10
Sys-Rev-SC11

C. Pubmed

Sys-Rev-SC12
Sys-Rev-SC13
Sys-Rev-SC14
Sys-Rev-SC15

5. Duplicate Removal(重複文献の削除)

4.の工程で以下のように3つのファイルがダウンロードされていると思います。

Sys-Rev-SC16

まずそれぞれのデータをわかりやすいように名前を変更しましょう。

Sys-Rev-SC17

ここで、以上の3つのファイルをmergeさせて、重複したペーパーについて取り除いていきます。以下のようなpythonファイルを用意して、実行しましょう。

すると、以下のようなことが実行されます。

wos.xlsscopus.csvpubmed.csvの読み込み

・2019年以前の論文のみ抽出(オプション)

・重複文献の削除

・各工程のスクリーニング数の記録(./output/hit_num.txt

・各文献の詳細データの入ったマスター表の出力(./output/master.xls

・抄録によるスクリーニングをするための表の出力(./output/check.xls

以下のコードは、Github – Masumi-M/systematic_review_pythonの中にも格納されています。

import numpy as np
import pandas as pd
text_path = "./output/hit_num.txt"
# Import Data
scp_raw = pd.read_csv('./scopus.csv')
wos_raw = pd.read_excel('./wos.xls')
pub_raw = pd.read_csv('./pubmed.csv')
print("=== Raw ===")
scp_preproc = scp_raw.copy()
scp_preproc = scp_preproc.loc[:, ['著者名', 'タイトル', '出版年', '出版物名', 'DOI', '抄録', '著者キーワード', '索引キーワード', '本文言語', '文献タイプ', '出版段階', '情報源', 'リンク']]
wos_preproc = wos_raw.copy()
wos_preproc = wos_preproc.loc[:, [ 'Authors', 'Article Title', 'Publication Year', 'Source Title', 'DOI', 'Abstract', 'Author Keywords', 'Keywords Plus', 'Language', 'Document Type', 'Research Areas', 'WoS Categories']]
pub_preproc = pub_raw.copy()
pub_preproc = pub_preproc.loc[:, ['Authors', 'Title', 'Publication Year', 'Journal/Book', 'DOI']]
print("=== Before 2019 ===")
scp_preproc_bef19 = scp_preproc.copy()
wos_preproc_bef19 = wos_preproc.copy()
pub_preproc_bef19 = pub_preproc.copy()
scp_preproc_bef19 = scp_preproc_bef19[scp_preproc_bef19['出版年'] < 2020]
wos_preproc_bef19 = wos_preproc_bef19[wos_preproc_bef19['Publication Year'] < 2020]
pub_preproc_bef19 = pub_preproc_bef19[pub_preproc_bef19['Publication Year'] < 2020]
print("scopus: " + str(len(scp_preproc_bef19)))
print("wos: " + str(len(wos_preproc_bef19)))
print("pubmed: " + str(len(pub_preproc_bef19)))
with open(text_path, mode='w') as f_hitnum: f_hitnum.write("scopus: " + str(len(scp_preproc_bef19)) + "\n") f_hitnum.write("wos: " + str(len(wos_preproc_bef19)) + "\n") f_hitnum.write("pubmed: " + str(len(pub_preproc_bef19)) + "\n\n")
total_1 = len(scp_preproc_bef19) + len(wos_preproc_bef19) + len(pub_preproc_bef19)
print("Total (1 - raw): " + str(total_1))
with open(text_path, mode='a') as f_hitnum: f_hitnum.write("Total (1 - raw): " + str(total_1) + "\n")
# 2. Preprocessing - Duplicate Removal
scp_preproc_bef19 = scp_preproc_bef19.rename(columns={'著者名': 'Authors','タイトル': 'Title','出版年':'Publication Year', '出版物名':'Journal/Book', '抄録':'Abstract', '著者キーワード':'Author Keywords', '索引キーワード':'Keywords Plus', '本文言語':'Language','文献タイプ':'Document Type'})
wos_preproc_bef19 = wos_preproc_bef19.rename(columns={'Article Title': 'Title', 'Source Title':'Journal/Book'})
data_merge = pd.concat([scp_preproc_bef19, wos_preproc_bef19, pub_preproc_bef19])
data_merge['Title_Lower'] = data_merge['Title'].str.lower()
data_merge = data_merge.drop_duplicates(['DOI'], keep='first')
data_merge = data_merge.drop_duplicates(['Title_Lower'], keep='first')
total_2 = len(data_merge)
print("Total (2 - duplicate removal): " + str(total_2))
with open(text_path, mode='a') as f_hitnum: f_hitnum.write("Total (2 - duplicate removal): " + str(total_2) + "\n")
def show_list(col_name): col_list = data_merge[col_name].values col_list = np.sort(col_list) print(col_list)
# show_list('Language')
# show_list('Document Type')
# 3. Exclusion based on title and abstracts
data_merge_xls_master = data_merge.loc[:, ['Publication Year', 'Title', 'Abstract', 'Authors', 'Journal/Book', 'Language', 'DOI', 'Document Type', 'Research Areas', '出版段階','Author Keywords','Keywords Plus', '情報源', 'リンク']]
data_merge_xls_check = data_merge.loc[:, ['Publication Year', 'Title', 'Abstract']]
data_merge_xls_check['include'] = 0
data_merge_xls_check['exclude'] = 0
data_merge_xls_check['note'] = ''
xlsx_path_master = './output/master.xlsx'
xlsx_path_check = './output/check.xlsx'
data_merge_xls_master.to_excel(xlsx_path_master, sheet_name='masterdata')
data_merge_xls_check.to_excel(xlsx_path_check, sheet_name='check_data')
print("===== Download Xlsx Done. =====")

6. Abstract Screening(抄録からスクリーニング)

続いて、5.の工程で出力した抄録のチェック表を用いて、スクリーニングを行なっていきます。 PRISMAのガイドラインではAbstract Screeningの際は、Reasoningを必要としていませんが、スクリーニングを行う前にどのような基準で取捨選択をするかを決めておくといいと思います。参考程度に考えられる基準を列挙します。

・英語以外の言語で書かれていた。

・Review論文だった。

・Out of Focusな内容だった。

・査読なし論文だった。

・原著論文ではなく、学会誌だった。

・定めた期間外の論文だった。

7. Full-Text Article Screening(論文全体からスクリーニング)

ここでは、TitleとAbstractだけでは判断できなかった論文のスクリーニングを行なっていきます。 基本的に目的としている論文じゃないものを外していきます。この際、どういう基準でスクリーニングを行なったかを明示する必要があります。

8. Flow Diagram Visualization(スクリーニング工程の図示化)

ここまで行なったスクリーニングの結果、各工程でどのようにして、論文数が変化したかを図におこします。PRISMAのホームページにサンプルのFigureが上がっているため、こちらを参考にするといいと思います(PRISMA flow diagram)。

9. Analysis(スクリーニングした論文から解析)

スクリーニングした論文(Included Paper)の効果量を統合したり、定性的な結果をまとめたりします。あらかじめ決めていた解析手法で解析をしましょう。

10. Publication (アウトプット)

結果が出たら、ぜひ学会や論文などとしてPublishしましょう。

最後に

いかがだったでしょうか?
この記事を通して、少しでもあなたの困りごとが解決したら嬉しいです^^

おまけ(お知らせ)

エンジニアの仲間(データサイエンティストも含む)を増やしたいため、公式LINEを始めました🎉

「一緒に仕事をしてくれる方」「友だちとして仲良くしてくれる方」は、友だち追加をしていただけますと嬉しいです!(仲良くなった人たちを集めて、「ボードゲーム会」や「ハッカソン」や「もくもく会」もやりたいなと考えています😆)

とはいえ、みなさんにもメリットがないと申し訳ないので、特典を用意しました!

友だち追加後に、アンケートに回答してくれた方へ「エンジニア図鑑(職種20選)」のPDFをお送りします◎