京橋のバイオインフォマティシャンの日常

南国のビーチパラソルの下で、Rプログラムを打ってる日常を求めて、、Daily Life of Bioinformatician in Kyobashi of Osaka

【Rのジミ〜な小技シリーズ】Rのどぎついレインボー・カラーを和らげて、使える色へと変換するTipsについて

はじめに

楽なので、Rのplot()時に、レインボー色(grDevices::rainbow)を使うんだけど、 お世辞にも良い色とは言えず、ドギツイ色を使うねと周囲から言われる。

今回、それを挽回するために、そのレインボー色を和らげる方法を紹介する。

rainbow関数では、16進数で表される「カラーコード」*1 + 透明度が出力される。 そのため、透明度の設定を変更すると、程良いレインボー・カラーにすることができる。

例えば、grDevices::rainbow(10)の出力結果は、次のようになる。

grDevices::rainbow(10)

 [1] "#FF0000FF" "#FF9900FF" "#CCFF00FF"
 [4] "#33FF00FF" "#00FF66FF" "#00FFFFFF"
 [7] "#0066FFFF" "#3300FFFF" "#CC00FFFF"
[10] "#FF0099FF"

最後の2桁 FF は、透明度ゼロ(非透明)という意味になるので、 そこを数字に置き換える。

この文字列処理には、文字列の部分抽出ができる、base::substr関数を使用する。 substr関数で、カラーコードの1文字目から7文字目までを抜き出して、 任意の数字2桁とくっ付ければ、色変換ができる。

実際に、FF、80、60、40、20でのプロット結果を見てみる*2

レインボー色(grDevices::rainbow関数)の設定

レインボー・カラー 透明度 FF

#プロットデータ
Data <- data.frame(X=1:10, Y=1:10)

#par設定
par(family="HiraKakuProN-W3", lwd=1.5, xpd=F, 
    mgp=c(2.5, 1, 0), mai=c(0.7,0.7, 0.2, 0.2))

#レインボー・カラー 透明度 FF
col100 <- rainbow(10)
col100
#上記と同じ
# [1] "#FF0000FF" "#FF9900FF" "#CCFF00FF"
# [4] "#33FF00FF" "#00FF66FF" "#00FFFFFF"
# [7] "#0066FFFF" "#3300FFFF" "#CC00FFFF"
#[10] "#FF0099FF"

plot(Data, cex=10, pch=21, col=1, bg=col100, xlim=c(0,11), ylim=c(0,11))

#図保存 for Mac
#quartz.save(paste("C100.png", sep=""), type = "png", dpi = 200)

https://kumes.github.io/Blog/Rainbow_plot/C100.png

レインボー・カラー 透明度 80

#レインボー・カラー 透明度 80
col80 <- paste(substr(rainbow(10), 1, 7), "80", sep="")

col80
# [1] "#FF000080" "#FF990080" "#CCFF0080"
# [4] "#33FF0080" "#00FF6680" "#00FFFF80"
# [7] "#0066FF80" "#3300FF80" "#CC00FF80"
#[10] "#FF009980"

plot(Data, cex=10, pch=21, col=1, bg=col80, xlim=c(0,11), ylim=c(0,11))
#quartz.save(paste("C080.png", sep=""), type = "png", dpi = 200)

https://kumes.github.io/Blog/Rainbow_plot/C080.png

レインボー・カラー 透明度 60

#レインボー・カラー 透明度 60
col60 <- paste(substr(rainbow(10), 1, 7), "60", sep="")
col60
# [1] "#FF000060" "#FF990060" "#CCFF0060"
# [4] "#33FF0060" "#00FF6660" "#00FFFF60"
# [7] "#0066FF60" "#3300FF60" "#CC00FF60"
#[10] "#FF009960"

plot(Data, cex=10, pch=21, col=1, bg=col60, xlim=c(0,11), ylim=c(0,11))
#quartz.save(paste("C060.png", sep=""), type = "png", dpi = 200)

https://kumes.github.io/Blog/Rainbow_plot/C060.png

レインボー・カラー 透明度 40

#レインボー・カラー 透明度 40
col40 <- paste(substr(rainbow(10), 1, 7), "40", sep="")
col40
# [1] "#FF000040" "#FF990040" "#CCFF0040"
# [4] "#33FF0040" "#00FF6640" "#00FFFF40"
# [7] "#0066FF40" "#3300FF40" "#CC00FF40"
#[10] "#FF009940"

plot(Data, cex=10, pch=21, col=1, bg=col40, xlim=c(0,11), ylim=c(0,11))
#quartz.save(paste("C040.png", sep=""), type = "png", dpi = 200)

https://kumes.github.io/Blog/Rainbow_plot/C040.png

レインボー・カラー 透明度 20

#レインボー・カラー 透明度 20
col20 <- paste(substr(rainbow(10), 1, 7), "20", sep="")
col20
# [1] "#FF000020" "#FF990020" "#CCFF0020"
# [4] "#33FF0020" "#00FF6620" "#00FFFF20"
# [7] "#0066FF20" "#3300FF20" "#CC00FF20"
#[10] "#FF009920"

plot(Data, cex=10, pch=21, col=1, bg=col20, xlim=c(0,11), ylim=c(0,11))
#quartz.save(paste("C020.png", sep=""), type = "png", dpi = 200)

https://kumes.github.io/Blog/Rainbow_plot/C020.png

Rで使える他のカラーパレットについて

palette()関数を使います。

R4.0以降、デフォルトのカラーパレットが変わっています。 新しいパレットでは以前同様の色相を使用していますが、 輝度の点でよりバランスが取れており、極端に派手な色合いを避けています。

palette()関数のデフォルトカラー 透明度 FF

#プロットデータ
Data <- data.frame(X=1:8, Y=1:8)

#par設定
par(family="HiraKakuProN-W3", lwd=1.5, xpd=F, 
    mgp=c(2.5, 1, 0), mai=c(0.7,0.7, 0.2, 0.2))

#デフォルト・パレット
pal100 <- palette()
pal100
#[1] "black"   "#DF536B" "#61D04F" "#2297E6" "#28E2E5"
#[6] "#CD0BBC" "#F5C710" "gray62" 

plot(Data, cex=10, pch=21, col=1, bg=pal100, xlim=c(0,11), ylim=c(0,11))

#図保存 for Mac
#quartz.save(paste("P100.png", sep=""), type = "png", dpi = 200)

 

palette()関数のデフォルトカラー 透明度 75

#プロットデータ
Data <- data.frame(X=1:8, Y=1:8)

#par設定
par(family="HiraKakuProN-W3", lwd=1.5, xpd=F, 
    mgp=c(2.5, 1, 0), mai=c(0.7,0.7, 0.2, 0.2))

#デフォルト・パレット 75
pal75 <- paste(c("#000000", palette()[c(-1, -8)], "#9e9e9e"), "75", sep="")
pal75
#[1] "#00000075" "#F8766D75" "#00BA3875" "#619CFF75"
#[5] "#00BFC475" "#F564E375" "#B79F0075" "#9e9e9e75"

plot(Data, cex=10, pch=21, col=1, bg=pal75, xlim=c(0,11), ylim=c(0,11))

#図保存 for Mac
#quartz.save(paste("P75.png", sep=""), type = "png", dpi = 200)

まとめ

プロットの種類によるけど、透明度は60くらいが良さそうに思う。

よって、paste(substr(rainbow(10), 1, 7), "60", sep="")を推奨。

補足

実は、もっと簡単には、rainbowの引数であるalpha値を設定しよう。

alpha値を「1より小さい値」に設定することで、半透明の設定ができる。

以下が実施例である。

alpha値 0.5 で、半透明の設定

#データの準備
Data <- data.frame(X=1:10, Y=1:10)

#alpha値 0.5 で、半透明の設定
col50 <- rainbow(10, alpha =0.5)
par(family="HiraKakuProN-W3", lwd=1.5, xpd=T, 
    mgp=c(2.5, 1, 0), mai=c(0.7,0.7, 0.2, 0.2))
plot(Data, cex=10, pch=21, col=1, bg=col50, xlim=c(0,11), ylim=c(0,11))
quartz.save(paste("C050.png", sep=""), type = "png", dpi = 200)

レインボーを逆順にする

#レインボーを逆順にする
col50_r <- rainbow(10, alpha =0.5, rev = T)
par(family="HiraKakuProN-W3", lwd=1.5, xpd=T, 
    mgp=c(2.5, 1, 0), mai=c(0.7,0.7, 0.2, 0.2))
plot(Data, cex=10, pch=21, col=1, bg=col50_r, xlim=c(0,11), ylim=c(0,11))
quartz.save(paste("C050_r.png", sep=""), type = "png", dpi = 200)

ちょっと落ち着いた感じのレインボー・プロット

#ちょっと落ち着いた感じのレインボー・プロット
library(colorspace)
ColorSpa <- colorspace::rainbow_hcl(10, alpha = 0.5)
par(family="HiraKakuProN-W3", lwd=1.5, xpd=T, 
    mgp=c(2.5, 1, 0), mai=c(0.7,0.7, 0.2, 0.2))
plot(Data, cex=10, pch=21, col=1, bg=ColorSpa, xlim=c(0,11), ylim=c(0,11))
quartz.save(paste("C050_ColorSpa.png", sep=""), type = "png", dpi = 200)

【Rのジミ〜な小技シリーズ】

skume.net

skume.net

skume.net

skume.net

skume.net

skume.net

skume.net

skume.net

skume.net

*1:https://woma2.com/design/colorcodes-post-1203/

*2:透明度が分かるよう、あえてマーカーを重ねてみた

【Rのジミ〜な小技シリーズ】時々にしたくなる、Rの古いバージョンのパッケージ(The previous version packages)をインストールする件

はじめに

Rを使っていると、稀に、パッケージのバージョン違いで問題が起こることがあります。

そのとき、以前の古いバージョンのパッケージをインストールする必要がでてきます。。

今回はそういう時のお話です。

過去のバージョンのRパッケージをインストールする

以前のバージョンをインストールする場合には、まず、CRANのパッケージのページにいきます。

例えば、psychパッケージだと、以下のURLになります。

CRAN - Package psych

そこで、Downloads:にある、psych archiveをクリックして、アーカイブのページにはいります。

そこのアーカイブのなかから、必要なバージョンを探します。

ここでは、1つ前のバージョン 1.9.12 を入れるので、そのリンクをコピーします*1

次に、Rを起動して、以下の命令文を実行すれば、インストールは完了します。

さて、やってみましょう。

#さきほどのリンクをペーストする
URL <- "https://cran.r-project.org/src/contrib/Archive/psych/psych_1.9.12.tar.gz"

#type="source"で実行する
install.packages(URL, repos=NULL, type="source")

#URL 'https://cran.r-project.org/src/contrib/Archive/psych/psych_1.9.12.tar.gz' を試しています 
#Content type 'application/x-gzip' length 1720133 bytes (1.6 MB)
#==================================================
#downloaded 1.6 MB
#
#* installing *source* package ‘psych’ ...
#**  パッケージ ‘psych’ の解凍および MD5 サムの検証に成功しました 
#** using staged installation
#** R
#** data
#*** moving datasets to lazyload DB
#** inst
#** byte-compile and prepare package for lazy loading
#** help
#*** installing help indices
#** building package indices
#** installing vignettes
#** testing if installed package can be loaded from temporary location
#** testing if installed package can be loaded from final location
#** testing if installed package keeps a record of temporary installation path
#* DONE (psych)

つづいて、インストールしたpsychパッケージのバージョンを確認します。

packageVersion("psych")

まとめ

以前のバーション・過去バージョンのインストールは、 タマーにしないといけず、どうやったっけ?と戸惑うので、メモしておきます。。

ジミ〜〜ですが、大切なことですよね。

【Rのジミ〜な小技シリーズ】

skume.net

skume.net

skume.net

skume.net

skume.net

skume.net

skume.net

skume.net

skume.net

*1:アーカイブでは、下の方ほど、新しいパッケージです

【R言語と学術論文】PubMed API「RISmed」と googletrans を使って、PubMed掲載論文のAbstract和訳をRでやってみた件

はじめに

論文のトレンド解析であったり、個別の論文情報、主に要旨(Abstract)を取得してみた。 もう少し発展させて、Abstractの英文テキストの和訳をして、Rmarkdownのレポート作成するまでをやってみた。

今回扱う、RISmed パッケージは、PubMedを含むNational Center for Biotechnology Information (NCBI: アメリカ国立生物工学情報センター)のデータベースから論文情報を抽出するためのツール群である*1

また、Abstractのテキスト和訳には、以前の記事で紹介した、Pythonの googletrans ライブラリを使用する。

skume.hatenablog.com

Rパッケージのセットアップ

6つのRパッケージをインストール・ロードしておく。

if(!require("RISmed")){install.packages("RISmed")}; library(RISmed)
if(!require("magrittr")){install.packages("magrittr")}; library(magrittr)
if(!require("purrr")){install.packages("purrr")}; library(purrr)
if(!require("plotly")){install.packages("plotly")}; library(plotly)
if(!require("progress")){install.packages("progress")}; library(progress)
if(!require("reticulate")){install.packages("reticulate")}; library(reticulate)

RISmedパッケージで主に使用する関数は、EUtilsSummaryEUtilsGetである。

EUtilsSummary: NCBIのデータベースに対するクエリの結果の概要情報を取得する関数。

EUtilsGet: NCBIのデータベースに対する検索結果をダウンロードする関数。

PubMed全体でキーワード検索をやってみる

"3d electron microscopy" (3D電顕)をキーワードに検索してみる。

# キーワード検索
SearchTerm <- "3d electron microscopy"

#PubMed検索
esearchResults <- SearchTerm %>% 
  EUtilsSummary(query=., type="esearch", db="pubmed", retmax=10000)

#Queryとヒット数
summary(esearchResults)
#Query:
#3d[All Fields] AND ("microscopy, electron"[MeSH Terms] OR ("microscopy"[All Fields] AND 
#"electron"[All Fields]) OR "electron microscopy"[All Fields] OR ("electron"[All Fields] AND 
#"microscopy"[All Fields])) 
#Result count:  7077

#データ構造の出力
str(esearchResults)
#Formal class 'EUtilsSummary' [package "RISmed"] with 6 slots
#  ..@ db              : chr "pubmed"
#  ..@ count           : num 7077
#  ..@ retmax          : num 7077
#  ..@ retstart        : num 0
#  ..@ PMID            : chr [1:7077] "32573315" "32571921" "32571173" "32569437" ...
#  ..@ querytranslation: chr "3d[All Fields] AND (\"microscopy, electron\"[MeSH Terms] OR 
# (\"microscopy\"[All Fields] AND \"electron\"[All Fi"| __truncated__

次に、2020年の掲載論文に対して、キーワード検索を行ってみる。

Year <- 2020
SearchTerm <- "3d electron microscopy"

esearchResults2020 <- SearchTerm %>% 
  EUtilsSummary(query=., type="esearch", db="pubmed", mindate=Year, maxdate=Year, retmax=10000)

#ヒット数の表示
QueryCount(esearchResults2020)
#OR
esearchResults2020@count
#[1] 312

次に、ヒットしたPMID*2をもとに、論文情報(雑誌名、論文タイトル、Abstract、MeSHとか)を検索してみる。

#PMIDを出力する
PubID <- QueryId(esearchResults2020)
PubID

#  [1] "32573315" "32571921" "32571173" "32569437" "32567732"
#  [6] "32566142" "32565223" "32559707" "32557536" "32556943"
# [11] "32554894" "32548815" "32548814" "32545804" "32545376"
# ......

#PMIDから、1つ目の論文情報(PMID "32573315")の検索
PubIDResults <- PubID[1] %>%
 EUtilsGet(type="efetch", db="pubmed")

PubIDResults
#PubMed query:   
#   Records:  1 

#Mesh headingsを調べる
Mesh(PubIDResults)
#[[1]]
#[1] NA
#ただし、この論文はMeshが付与されてないみたい

MeSH (Medical Subject Headings) は、米国国立医学図書館 (National Library of Medicine; NLM)で定める生命科学用語集(シソーラス)である。調べた論文はNAだったが、文献の内容を表す適切なMeSH用語を10〜15個程度文献に付与し、この用語により文献を検索・管理できるようにしているらしい*3

#データのリスト化
Results <- list(PubIDResults@PMID,
                PubIDResults@Author,
                PubIDResults@Title,
                PubIDResults@ArticleTitle,
                PubIDResults@AbstractText)

データをリスト化しておく、データ表示については後述する。

少し脱線して、年ごとの論文数をまとめてみた

年ごとの論文数をまとめることで、そのキーワードの研究トレンドを把握できると考えられる。

そこで、対象キーワードの年ごとの論文数を集計する関数を導入する。

PubNumber <- function(i){
  r <- EUtilsSummary(terms, type='esearch', db='pubmed', mindate=i, maxdate=i)
  return(QueryCount(r))
}

この関数に対して、map関数で、年数のベクトル値(i)とキーワード(terms)を与えてあげると、年ごとの論文数を検索できる。

コロナウィルス(Coronavirus)をキーワードに、1970-2020年の1年ごとで論文数を検索して、可視化みる。

#Coronavirus publications in PubMed 
terms <- "Coronavirus"
Years <- 1970:2020

PubNum <- purrr::map(Years, PubNumber)
Data <- data.frame(Years, PubNumber=unlist(PubNum))

fig <- plot_ly(Data, x = ~Years, y = ~PubNumber, type = 'bar', name = 'Publications',
               marker = list(color = 'rgb(158,202,225)', line = list(color = 'rgb(8,48,107)', width = 1)))
fig <- fig %>% layout(title = paste("Number of PubMed articles containing ", terms, sep=""),
                      yaxis = list(title = 'Count'),
                      xaxis = list(title = "Year"))
fig

https://kumes.github.io/Blog/Search_PubMed/Coronavirus.html

今年すでに論文数が10倍以上に爆増している。。。*4

さらに、ディープラーニング(Deep learning)について同じく検索してみる。

#Deep learning publications in PubMed 
terms <- "deep learning"
Years <- 1970:2020

PubNum <- purrr::map(Years, PubNumber)
Data <- data.frame(Years, PubNumber=unlist(PubNum))

fig <- plot_ly(Data, x = ~Years, y = ~PubNumber, type = 'bar', name = 'Publications',
               marker = list(color = 'rgb(158,202,225)', line = list(color = 'rgb(8,48,107)', width = 1)))
fig <- fig %>% layout(title = paste("Number of PubMed articles containing ", terms, sep=""),
                      yaxis = list(title = 'Count'),
                      xaxis = list(title = "Year"))
fig

https://kumes.github.io/Blog/Search_PubMed/Deep_learning.html

2015-2016年あたりから、生命科学分野でのディープラーニングの応用が目覚ましいものといえる。

いちおう、この検索とグラフ化を1つの関数にしたので、以下の2行で同じことが実行できる(はず)。

source("https://gist.githubusercontent.com/kumeS/a9e612c6bb484451e6328f119fd9ef56/raw/481884897a54e51bc67b7dbd794fcfe9404a8166/PublicationPerYear.R")

PublicationPerYear(Term="deep learning")

本題に入って、googletransによる論文情報の和訳とレポート作成をやってみる

さきほどResultsにリストとして格納した論文情報を和訳してみる。

#念のため、別変数に置き換え
translatedResults <- Results

#Pythonパスの設定とgoogletransライブラリの読み込み
reticulate::use_python("/usr/local/bin/python", required =T)
gt <- reticulate::import(module = "googletrans")$Translator()

#エラーの原因となる、ゴミ文字を消しておく
TEXT01 <- gsub("&quot;", "", translatedResults[[5]])

#雑誌名、論文タイトル、Abstractの順にgoogletransによる和訳の実行
translateResults01 <- gt$translate(text=Results[[3]], src="en", dest='ja')
translateResults02 <- gt$translate(text=Results[[4]], src="en", dest='ja')
translateResults03 <- gt$translate(text=TEXT01, src="en", dest='ja')

#処理関数の定義
"CutText" <- function(x){
  strsplit(strsplit(as.character(x), ", text=")[[1]][2], ", pronunciation=")[[1]][1]
}

#結果の上書き
translatedResults[[3]][2] <-CutText(translateResults01)
translatedResults[[4]][2] <-CutText(translateResults02)
translatedResults[[5]][2] <-CutText(translateResults03)

#結果出力
translatedResults

変数のままだと、テキストが読みにくいので、RMarkdownでhtmlファイルを生成してみる。

以前の記事に倣って、wgetはインストールしておくこと。

skume.hatenablog.com

#RMarkdownフォーマットのダウンロード
system('wget https://gist.githubusercontent.com/kumeS/8a4410c7f9d07a0b49192bcda4bf1e03/raw/b8db496b0c13fa98affd654f03d45e17cf41ea08/Basic_report_jpn.Rmd')

#レンダリング(変数名は上記と同じにしておく)
rmarkdown::render("Basic_report_jpn.Rmd", 
                  output_format = "html_document", 
                  output_file = "output.html")

#htmlのブラウザ表示
browseURL("output.html")

https://kumes.github.io/Blog/Search_PubMed/report_output.html

こんな感じの簡易Rmarkdownレポートが出力される。

まとめ

トレンド解析とともに、論文のサーチを定期的にちゃんとやるきっかけになればと期待したい。

全Rコード in gist

To search the PubMed DB and translate the abstract to the Japanese text. · GitHub

補足

MEDLINEタグ情報*5

PubMedで、文献検索を行うときに、検索クエリに語句を記入して検索すると、タイトル、要旨、著者、MeSH等どこかに含まれる文献が検索される。

雑誌名に限定したい場合や、タイトルに限定したい場合は、タグを指定することで限定できる。

例えば、"cancer"[TA] とすることで、cancer という雑誌で指定できる。応用として、AND、OR、NOT を使って2つ以上の検索結果の論理積・論理和・論理否定も求められる。論理式は大文字で書くことでキーワードと区別される。

PubMedにおける主要なタグ

データフィールド タグ 説明
Affiliation [AD] 筆頭著者の所属機関
All Fields [ALL] 全てのフィールド
Author [AU] 著者。名字+名前の頭文字。徳川家康なら"Tokugawa I"[AU]。名字だけでもOK
First Author [1AU] 筆頭著者
Publication Date [DP] 発行日、2001[DP]等で指定
Full Author Name [FAU] 著者のフルネーム
Last Author [LASTAU] 最終著者
MeSH Terms [MH] MeSH用語で付与された文献の主題
MeSH Major Topic [MAJR] MeSH用語で付与される10~15の主題のうち、2つ程度の主要用語
Page Number [PG] ページ
PMID [PMID] PubMed登録番号
Journal [TA], [JO] 雑誌名
Title [TI] タイトル
Title/Abstract [TIAB] タイトルあるいは要旨
Text word [TW] テキスト本文

参考文献

rpubs.com

datascienceplus.com

amunategui.github.io

stackoverflow.com

plotly.com

*1:https://cran.r-project.org/web/packages/RISmed/index.html

*2:PubMed に収録されている論文にはPubMed ID (PMID) と呼ばれるIDが付与されている

*3:https://ja.wikipedia.org/wiki/MeSH

*4:この図は、2020年6月22日の結果で、6/25には論文数は15k以上になっていた。

*5:https://ja.wikipedia.org/wiki/MEDLINE