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

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

R言語でヒートマップ入門:インタラクティブなヒートマップでデータ分析をもっと楽しくしよう!!

はじめに

過去に、heatmap.2パッケージと階層的クラスタリングを使って、ヒートマップの描く方を紹介しました。 こんなヒートマップでした。いま思うと、懐かしいような、古めかしい感じがしますね。

 

今回は、R言語でのヒートマップの特集ということで、 色々なパッケージのヒートマップ表現を調査して、取り上げてみました。

ヒートマップとは、データを可視化するため、 「数値データの高い・低いの表」を「色や濃淡」セルのグリットに変換して表現した視覚化法、あるいはデータ解析法の1つです。 数値の一覧を目視するよりも、データ間の意味や差異がより直感的に導けますし、 「色や濃淡」の曖昧な表現から、データ全体のニュアンスを掴む行為とも言えます。

また、項目間の近縁関係のパターンを強調するために並べられ、しばしばデンドログラムが添えられます。 こうすることで、ヒートマップの見え方が大きく変わり、データからふとした新しい発見にも繋がるかもで、 それは、このヒートマップ解析の興味深いところです。 ヒートマップは、観測値、相関関係、欠損値パターンなどを可視化するために、多くの分野で使用されています。

この記事では、色々なパッケージでのヒートマップの作り方に加えて、 インタラクティブにヒートマップを作成・可視化できるパッケージを紹介します。 全体を通じて、ツール間の比較ができ、良し悪しも感じてもらえるのではと思います。

実行環境

実行環境は以下の通りです。

macOS Big Sur (バージョン11.5.2)
MacBook Air (M1, 2020)
チップ Apple M1
メモリ 16GB

Rパッケージの読み込み

R環境を立ち上げて、必要なパッケージをインストールしておきます。

#パッケージ・インストール
pack <- c("htmlwidgets", "qtlcharts", "qtl", "iheatmapr", "heatmap3", "heatmaply", "remotes", "corrplot")
install.packages(pack[!(pack %in% unique(rownames(installed.packages())))])

#ロード
for(n in 1:length(pack)){ eval(parse(text = paste0("library(", pack[n], ")"))) }; rm("n", "pack")

heatmap3パッケージを用いた、ハイカラなヒートマップ表現

heatmap2というパッケージがありますが、最近、heatmap3というのも出ているようです。

heatmap3は、改良されたヒートマップパッケージで、Rのオリジナル関数'heatmap'と 完全な互換性で、便利な機能を提供すると説明されています。

それでは、早速、heatmap3のサンプルコードを実行してみます。

heatmap3でのヒートマップ作成(1)シンプルなヒートマップ

この実行例では、乱数を生成して、サンプルデータを作成・利用して、シンプルなヒートマップを作成します。

#乱数でサンプルデータ作成
rnormData <- matrix(rnorm(1000), 40, 25)
#head(rnormData)

#微調整
rnormData[1:15, seq(6, 25, 2)] <- rnormData[1:15, seq(6, 25, 2)] + 2
rnormData[16:40, seq(7, 25, 2)] = rnormData[16:40, seq(7, 25, 2)] + 4

#列名を与える
colnames(rnormData) <- c(paste("Control", 1:5, sep = ""),
                         paste(c("TrtA", "TrtB"), rep(1:10,each=2), sep = ""))
#行名を与える
rownames(rnormData) <- paste("Probe", 1:40, sep = "")

#グループのカラーリング
ColSideColors <- cbind(Group1=c(rep("steelblue2",5), rep(c("brown1", "mediumpurple2"),10)),
                       Group2=sample(c("steelblue2","brown1", "mediumpurple2"),25,replace=TRUE))

#特定セルのカラーリング
colorCell <- data.frame(row=c(1,3,5),col=c(2,4,6),
                      color=c("green4","black","orange2"),stringsAsFactors=FALSE)

#特定セルのハイライト
highlightCell <- data.frame(row=c(2,4,6),col=c(1,3,5),
                            color=c("black", "green4","orange2"),lwd=1:3,stringsAsFactors=FALSE)

#ヒートマップ実行
heatmap3(rnormData,
         ColSideColors=ColSideColors, 
         showRowDendro=FALSE,
         colorCell=colorCell,
         highlightCell=highlightCell)

#注釈
#ColSideColors: 水平サイドバーの色名を含む長さncol(x)の文字ベクトル
#showRowDendro: 行のデンドログラムをプロットするかどうかを指定する論理値
#colorCell: 3つの列を持つ data.frame で、どのセルが特定の色で着色されるか
#highlightCell: 3列または4列の data.frame で、どのセルが特定の色の矩形でハイライトされるか

 

このヒートマップはインタラクティブではない分、見栄えが良いような気がしますね。

heatmap3でのヒートマップ作成(2)少し複雑なヒートマップ

次には、少し複雑なヒートマップの作成を実行します。

#乱数でサンプルデータ作成
ColSideAnn <- data.frame(Information=rnorm(25),
                         Group=c(rep("Control",5),rep(c("TrtA","TrtB"),10)),
                         stringsAsFactors=TRUE)

#行名を与える(上記の実行から使用した変数転用)
row.names(ColSideAnn) <- colnames(rnormData)

#カラーパレット作成
RowSideColors <- colorRampPalette(c("chartreuse4", "white", "firebrick"))(40)

result <- heatmap3(rnormData,
                   ColSideCut=1.2,
                   ColSideAnn=ColSideAnn,
                   ColSideFun=function(x) {showAnn(x)},
                   ColSideWidth=0.8,
                   RowSideColors=RowSideColors,
                   col=colorRampPalette(c("green","black", "red"))(1024),
                   RowAxisColors=1,
                   legendfun=function() {showLegend(legend=c("Low","High"), col=c("chartreuse4","firebrick"))},
                   verbose=TRUE)
#注釈
#ColSideCut: coloumデンドログラムをカットする際に使用される数値
#ColSideAnn: 連続変数と因子変数をアノテーション情報として持つデータフレーム。
#ColSideFun: 列方向に注釈やラベリング図を生成するために使用される関数
#ColSideWidth: 数値列の側面領域の高さ
#RowSideColors: (オプション) nrow(x) の長さの文字ベクトル
#RowAxisColors: RowSideColors のどの色を行軸のラベルの色として使用するかを示す整数値
#legendfun: 関数で、図の左上に凡例を生成する。

 

実際、ヒートマップの調整は結構ややこしいです。

heatmaplyパッケージを使った、ヒートマップ作図

次に、heatmaplyパッケージは、ggplot2とplotly.jsのエンジンをベースにして開発されています。 d3heatmapと同様のヒートマップを生成しますが、plotly.jsはより大きなサイズの行列を扱えて、 デンドログラムからのズーム機能の点で優れているようです。

デフォルトのplot_method = "ggplot"の代わりに、 plot_method = "plotly"を選択することもできます。

heatmaplyによる通常のヒートマップ

まずは、mtcarsのデータセットで、heatmaply関数のシンプル実行をしてみます。

#データ表示
head(mtcars)
#                   mpg cyl disp  hp drat    wt  qsec vs am gear carb
#Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
#Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
#Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
#Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
#Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
#Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

#実行
heatmaply(mtcars)

https://kumes.github.io/Blog/R_heatmap/04_heatmaply.html

heatmaply_corによる相関ヒートマップ

heatmaply_corは、相関行列に適したヒートマップ関数です。 具体的には、限界値は -1 から 1 に設定され、 カラーパレットはRdBuになっています。

#実行
heatmaply_cor(
  x = cor(mtcars),
  xlab = "Features",
  ylab = "Features",
  k_col = 2,
  k_row = 2
)

https://kumes.github.io/Blog/R_heatmap/05_heatmaply_cor.html

heatmaplyによるpercentizeヒートマップ

percentize関数を使った、経験的パーセンタイル変換は、変数のランクを取ることに似た挙動です。 違いは、変換された変数を比較したり解釈したりするのがよりシンプルになることです。

これは、ヒートマップ(例:heatmaply)において、複数の変数を比較するのに便利な側面があります。

#実行
heatmaply(
  percentize(mtcars),
  xlab = "Features",
  ylab = "Cars", 
  main = "Data transformation using 'percentize'"
)

https://kumes.github.io/Blog/R_heatmap/06_heatmaply_percentile.html

qtlchartsパッケージのiplotCorrを利用した、相関行列のヒートマップ表現

qtlchartsパッケージは、D3.jsを使った、ウェブベースのインタラクティブチャートを提供しています。 パッケージの主な用途は、遺伝子座を実験的に同定するための解析ツールのようです。 その中の1つの関数である、iplotCorrを使用します。

#データ読み込み
data(geneExpr)

#設定
chartOpts <- list(cortitle="Correlation matrix", scattitle="Scatterplot")

#ヒートマップ実行
iplotCorr(mat=geneExpr$expr, group=geneExpr$genotype, 
          reorder=TRUE, chartOpts=chartOpts)

https://kumes.github.io/Blog/R_heatmap/07_iplotCorr.html

次に、Spearmanの相関行列を使う方法です。

# Spearmanの相関行列計算
corr <- cor(geneExpr$expr, method="spearman", use="pairwise.complete.obs")

#設定
chartOpts <- list(cortitle="Spearman matrix", scattitle="Scatterplot")

# 階層的クラスタリングによる並び替え
o <- hclust(as.dist(1-corr))$order

#ヒートマップ実行
iplotCorr(mat=geneExpr$expr[,o], group=geneExpr$genotype, 
          corr=corr[o,o], chartOpts=chartOpts)

https://kumes.github.io/Blog/R_heatmap/08_iplotCorr.html

iheatmaprパッケージを用いたヒートマップ作成

iheatmaprパッケージは、複雑かつインタラクティブなヒートマップを構築するためのRパッケージです。

#データ読み込み
data(measles, package = "iheatmapr")

#ヘッド表示
head(measles)
#                1930  1931  1932  1933  1934
#ALABAMA         4389  8934   270  1735 15849
#ALASKA             0     0     0     0     0
#AMERICAN.SAMOA     0     0     0     0     0
#ARIZONA         2107  2135    86  1261  1022
#ARKANSAS         996   849    99  5438  7222
#CALIFORNIA     43585 27807 12618 26551 25650

#実行:メインのみ
main_heatmap(measles, name = "Measles<br>Cases", x_categorical = FALSE,
             layout = list(font = list(size = 8)))

まずは、main_heatmapのみの結果です。

https://kumes.github.io/Blog/R_heatmap/09_iheatmapr_main.html

#実行
main_heatmap(measles, name = "Measles<br>Cases", x_categorical = FALSE,
             layout = list(font = list(size = 8))) %>%
  add_col_groups(ifelse(1930:2001 < 1961,"No","Yes"),
                  side = "bottom", name = "Vaccine<br>Introduced?",
                  title = "Vaccine?",
                  colors = c("lightgray","blue")) %>%
  add_col_labels(ticktext = seq(1930,2000,10),font = list(size = 8)) %>%
  add_row_labels(size = 0.3,font = list(size = 6)) %>% 
  add_col_summary(layout = list(title = "Average<br>across<br>states"),
                  yname = "summary")  %>%                 
  add_col_title("Measles Cases from 1930 to 2001", side= "top") %>%
  add_row_summary(groups = TRUE, type = "bar",
                  layout = list(title = "Average<br>per<br>year",
                                font = list(size = 8)))

main_heatmapの結果に、6つのレイアーを付与して、最終的に複雑なヒートマップ図を作成します。

https://kumes.github.io/Blog/R_heatmap/10_iheatmapr.html

corrplotパッケージを用いた、相関ヒートマップ解析

corrplotは、相関行列を視覚的に探索するツールで、変数間の隠れたパターンを検出するのに役立ちます。また、自動的な変数の並べ替えをサポートしています。また、可視化方法、グラフィックレイアウト、色、凡例、テキストラベルなど、豊富なプロットオプションを提供しています。相関の統計的な有意性を判断するためのp値や信頼区間も提供しています。

#データ準備: mtcarsは自動車の燃費などに関するデータ
head(mtcars)
#                   mpg cyl disp  hp drat    wt  qsec vs am gear carb
#Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
#Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
#Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
#Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
#Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
#Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

#相関の計算
M <- cor(mtcars)

#デフォルト相関行列
corrplot(M, method = 'circle')

#数字表示有りの相関行列
corrplot(M, method = 'number') # colorful number

corrmorantを使った、相関行列マップ

ヒートマップのパッケージとは言い難いのですが、、このパッケージも追記しておきます。

corrmorantパッケージは、通常のggplot2構文で相関行列のプロットを作図できます。 さらに、相関行列に基づく探索的データ解析のための大規模な可視化ツール群を提供しています。

#インストール
remotes::install_github("r-link/corrmorant")
library(corrmorant)

#データ読み込み
data(drosera)

#表示
head(drosera)
#   species variety petiole_length petiole_width blade_length blade_width
#1 capensis   rubra          54.00          1.95        38.30        3.95
#2 capensis   rubra          45.90          1.15        27.60        2.95
#3 capensis   rubra          21.20          0.85        21.85        2.65
#4 capensis   rubra          56.40          1.65        38.20        3.30
#5 capensis   rubra          28.60          1.00        15.80        2.80
#6 capensis   rubra          32.85          1.50        24.65        4.40

#詳細
str(drosera)
#'data.frame': 150 obs. of  6 variables:
# $ species       : Factor w/ 3 levels "capensis","madagascariensis",..: 1 1 1 1 1 1 1 1 1 1 ...
# $ variety       : Factor w/ 3 levels "alba","rubra",..: 2 2 2 2 2 2 2 2 2 2 ...
# $ petiole_length: num  54 45.9 21.2 56.4 28.6 ...
# $ petiole_width : num  1.95 1.15 0.85 1.65 1 1.5 1.85 1.65 2.4 1.5 ...
# $ blade_length  : num  38.3 27.6 21.9 38.2 15.8 ...
# $ blade_width   : num  3.95 2.95 2.65 3.3 2.8 4.4 4.8 3.4 3.9 4.4 ...

それでは、droseraのデータを使って、ggcorrmを実行します。 mappingで、colとfillにはspeciesの列を指定します。 2列目のvariety列が無視されるのは、Factorだからですかね。

#実行
ggcorrm(drosera, mapping = aes(col = species, fill = species)) +
  lotri(geom_smooth(alpha = 0.4, method = "lm")) +
  lotri(geom_point(alpha = 0.4)) +
  utri_corrtext(nrow = 2, squeeze = 0.6) +
  dia_names(y_pos = 0.15, size = 3) +
  dia_density(lower = 0.3, color = 1, alpha = 0.4)

#注釈
#lotri: プロットパネルのサブセットへのggplotレイヤーのマッピングを変更するために使用できるセレクタ関数
#utri_corrtext: プロットの非対角成分での二変量相関の強さをテキストラベルで表示するために使用されます。
#dia_names: プロットの変数名を対角成分の適切な位置にプロットします。
#dia_density: プロットの対角パネルに密度カーブを追加します。

以下のような、結果が得られます。

まとめ

R言語でのヒートマップ特集ということで、最近流行りのヒートマップ表現について調査してみました。 ヒートマップもインタラクティブな可視化が多くなってきている印象ですね。

1つのヒートマップ上に、色々な情報や解析結果を盛り込めるのは良いのですが、 実行コードが複雑で、覚えるのがやや面倒な感じがします。私だけでしょうか。。

参考資料

cran.r-project.org

kbroman.org

github.com

www.karada-good.net

github.com

cran.r-project.org

cran.r-project.org

github.com

【R言語とWebスクレイピングとアニメーショングラフ】仮想通貨や株価変動をバー・チャート・レースで観察してみた件【その2 ダウ・ジョーンズ工業株価平均(ダウ平均)編】

はじめに

いま。。このブログは、「アニメーショングラフ」推しです。

第二弾として、ダウ・ジョーンズ工業株価平均(ダウ平均)の各銘柄の時系列データ(日足)について、「バー・チャート・レース」を作成みました。

ダウ平均は、ちょうど、30銘柄なのでバーチャートにしても見易いです。

さぁ、アニメーショングラフをやっていきましょう。

実行環境

実行環境
macOS Big Sur (バージョン11.5.2)
MacBook Air (M1, 2020)
チップ Apple M1
メモリ 16GB

Rパッケージの準備

関連のRパッケージを準備します。結構あります。 ここをスキップして、以下のスクリプトを読み込むのでもOKです。

#パッケージ・インストール
pack <- c("rvest", "quantmod", "magrittr", "purrr", "tidyr", "ggplot2", "treemapify", "gganimate", "gapminder", "gifski")
install.packages(pack[!(pack %in% unique(rownames(installed.packages())))])

#ロード
for(n in 1:length(pack)){ eval(parse(text = paste0("library(", pack[n], ")"))) }; rm("n")

getDJIA.Rスクリプトを読み込んでも、Rパッケージがインストールできます。

同時に、今回使用する、getDJIA_list、DJIA_ChartData、DJIA_ChartData_mod、DJIA_animationといった関数群を読み込みます。各関数は、ダウ平均の30銘柄用に調整しています。

#関連関数群の読み込み
source("https://gist.githubusercontent.com/kumeS/b4c2a978b31dbe5fc3cb41c4d3e0b6ef/raw/95aefe669ef0ffcccec87e85a87e0d225d73cc71/getDJIA.R")

ではでは、早速、実行してみましょう。

ダウ平均銘柄のデータ取得

ダウ平均のウィキペディアページ

まず、getDJIA_list関数では、ウェブスクレイピングを介して、ウィキペディアの該当ページからダウ平均の銘柄リストを取得します。

ダウ平均の30銘柄の情報

ダウ平均の30銘柄の情報は、この表から取得します。シンボルやセクター情報も含まれます。

それでは、次に、DJIA_ChartData関数でデータを取得します。

#Wikipediaページからダウ平均銘柄リストを取得する
DJIAList <- getDJIA_list()

#表示
head(DJIAList)
#           Company Exchange Ticker                  Sector
#1               3M     NYSE    MMM            Conglomerate
#2 American Express     NYSE    AXP      Financial services
#3            Amgen   NASDAQ   AMGN       Biopharmaceutical
#4            Apple   NASDAQ   AAPL  Information technology
#5           Boeing     NYSE     BA   Aerospace and defense
#6      Caterpillar     NYSE    CAT Construction and Mining

#銘柄のセクター数
table(DJIAList$Sector)

#ダウ平均のデータ取得: 実行時間 2分くらい
ChartData <- DJIA_ChartData(Dat=DJIAList, term=c("2022-01-01", "2022-12-31"))

#いったん、RDS保存
saveRDS(ChartData, "DJIA_ChartData.Rds")
#ChartData <- readRDS("DJIA_ChartData.Rds")

#または、DJIA_ChartData.Rdsをダウンロードできるようにもしています。
#system("which svn")
#system("svn export  https://github.com/kumeS/Blog/trunk/R_BarChart/DJIA_ChartData.Rds")

#表示
head(ChartData)
#           Company Ticker                  Sector       date close dclose dclose2 ranking
#1               3M    MMM            Conglomerate 2022-01-03   100      0 #F0F5F0       1
#2 American Express    AXP      Financial services 2022-01-03   100      0 #F0F5F0       2
#3            Amgen   AMGN       Biopharmaceutical 2022-01-03   100      0 #F0F5F0       3
#4            Apple   AAPL  Information technology 2022-01-03   100      0 #F0F5F0       4
#5           Boeing     BA   Aerospace and defense 2022-01-03   100      0 #F0F5F0       5
#6      Caterpillar    CAT Construction and Mining 2022-01-03   100      0 #F0F5F0       6

このステップで、ダウ平均の30銘柄のリストとデータが取得できました。

ダウ平均銘柄でのバー・チャート・レース

ダウ平均銘柄のバー・チャート・レース作成

次に、ダウ平均銘柄のデータを使って、バー・チャート・レースを作成します。

DJIA_ChartData_mod関数で、ダウ平均の全銘柄のデータフレームにします。この関数で、rankingという列データを作成します。その後、DJIA_animation関数を実行して、チャート設定をします。また、日本語設定も別途します。

#データ補正: 全銘柄を取得する
ChartData1 <- DJIA_ChartData_mod(ChartData)

#表示
head(ChartData1)
#    Company Ticker       Sector CompanyTicker     CompanySector       date
#1        3M    MMM Conglomerate      3M (MMM) 3M (Conglomerate) 2022-01-03
#31       3M    MMM Conglomerate      3M (MMM) 3M (Conglomerate) 2022-01-04
#61       3M    MMM Conglomerate      3M (MMM) 3M (Conglomerate) 2022-01-05
#91       3M    MMM Conglomerate      3M (MMM) 3M (Conglomerate) 2022-01-06
#121      3M    MMM Conglomerate      3M (MMM) 3M (Conglomerate) 2022-01-07
#151      3M    MMM Conglomerate      3M (MMM) 3M (Conglomerate) 2022-01-10
#    close dclose dclose2 ranking
#1   100.0    0.0 #F0F5F0       1
#31  101.4    1.4 #F0F5F0      12
#61  101.0    1.0 #F0F5F0      15
#91  100.1    0.1 #F0F5F0      15
#121 101.2    1.2 #F0F5F0      14

#日本語設定: 必須
ggplot2::update_geom_defaults("text", list(family = "HiraKakuPro-W3"))
ggplot2::update_geom_defaults("label", list(family = "HiraKakuPro-W3"))

##実行
p1 <- DJIA_animation(ChartData1, Label="ダウ平均銘柄")

#gif出力: 実行時間 30秒くらい
animate(p1, fps = 2, duration = 125, width = 700, height = 700,
        renderer = gifski_renderer("DJIA_BarChartRace_animation_p1.gif"))

ダウ平均銘柄のバー・チャート・レース

まとめ

今回、ダウ平均銘柄の2022年12月まで値動きのバー・チャート・レースを作成しました。 全体を眺めてみると、12月20日現在で、2022年年初からで100%以上なっている銘柄は、約10銘柄あるみたいですね。 そのなかでも、シェブロン(CVX)とメルク(MRK)が結構上昇していて、目立ちますね。2022年は、石油と医薬品の年でしたね。

関連記事

skume.net

Rコード: getDJIA.R

gist.github.com

【R言語とケモインフォ】PubChemからの化合物の情報・構造の取得、およびOpen-Babelを使ったファイル形式変換についての諸々

はじめに

情報学と化学(バケガク)との融合領域を、「ケモインフォマティクス」というらしいです。略して、「ケモインフォ」です。 この用語の由来はchemistryinformaticsとを合わせた造語で、 私はあまり使ったことないですが、日本語では「情報化学」とも言われるようです。

今回、タンパク質とリガンドの結合予測を行う、ドッキングシミュレーションの下準備として、 PubChemからの化合物情報の取得、Open Babelを使った化合物構造の作成やフォーマット変換、PyMOLを使った構造可視化といった諸々についてまとめてみました。

Open Babelは、主に化学構造ファイルフォーマットを変換するために用いられるフリーソフトウェアで、化学構造ファイルの作成やエネルギーに基づく構造の最適化計算などを行えます。また、PyMOLは老舗のオープンソースの分子グラフィックスツールで、現在、Schrödinger社によって商品化されて提供されています。

では、始めてみましょう。

実行環境

実行環境は以下の通りです。

macOS Big Sur (バージョン11.5.2)
MacBook Air (M1, 2020)
チップ Apple M1
メモリ 16GB

Rパッケージの読み込み

R環境を立ち上げて、必要なパッケージをインストールしておきます。今回は少なめです。

#パッケージ・インストール
pack <- c("readr")
install.packages(pack[!(pack %in% unique(rownames(installed.packages())))])

#ロード
for(n in 1:length(pack)){ eval(parse(text = paste0("library(", pack[n], ")"))) }; rm("n", "pack")

Open-Babel & PyMolのインストールについて

Macの場合、HomebrewでOpen-BabelPyMolをインストールするのが便利です。

まずは、ターミナルを起動して、open-babelをbrewコマンドでインストールします。

#Open-Babel のインストール
brew install open-babel

#パス確認
which obabel
#/opt/homebrew/bin/obabel

#ヘルプ表示
obabel -H

#バージョン確認
obabel -V       
#Open Babel 3.1.0 -- Aug  5 2022 -- 07:11:30

Open-Babelをインストールすると、obabel、obconformer、obdistgen、obenergy、obfitなど、19個のコマンド群がインストールされます。主には、obabelを使います*1

次に、pymolをインストールします。現在、PyMOL(TM) Molecular Graphics System, Version 2.5.0.が使えます。

#pymolのインストール
brew install pymol

#パス確認
which pymol
#/opt/homebrew/bin/pymol

これで、open-babelpymolの設定は完了です。

また、画像結合時に使うので、ImageMagickもインストールしておきます。

#ImageMagickのインストール
brew install imagemagick

Open-Babelの基本動作

https://openbabel.org/docs/current/

ここでは、Open-Babelの基本的な使い方について解説します。 まずは、SMILES記法をスタートに、化学構造ファイルを作成する方法を紹介します。

SMILES形式は多くの種類の分子エディタにおいてもインポート可能で、二次元の図表あるいは三次元のモデルとして表示できます。また、CANGENアルゴリズムに基づいて1つの表記になるよう正規化された(canonical)ものを、カノニカルSMILESと呼ばれます。

実施例として、グルコースのSMILES形式を使って、2Dと3Dの構造ファイルを作成してみます。 グルコースのCanonical SMILESは、「C(C1C(C(C(C(O1)O)O)O)O)O」と記述されます。

まずは、obabelコマンドを使って、グルコースのSMILESを2D画像(.png)に変換します。SMILESの入力については、-:"<SMILES string>" or -:'<SMILES string>'と記述します。また、別記法として、smiファイルを使う方法、echoを使う方法も記載しています。

それでは、ターミナルでコマンドを実行していきます。

#SMILESを2D画像に変換 + --gen2D
obabel -:'C(C1C(C(C(C(O1)O)O)O)O)O' -o png -O out1.png --gen2D

#SMILESを3D画像に変換 + --gen3D
obabel -:'C(C1C(C(C(C(O1)O)O)O)O)O' -o png -O out2.png --gen3D

#別記法(1): smiファイルを使う場合
echo 'C(C1C(C(C(C(O1)O)O)O)O)O' > glucose.smi
head glucose.smi
#C(C1C(C(C(C(O1)O)O)O)O)O
obabel -i smi glucose.smi -o png -O out3.png --gen3D

#別記法(2): echoを使う
#SMILESを2D画像に変換
echo 'C(C1C(C(C(C(O1)O)O)O)O)O' | obabel -i smi -o png -O out4.png --gen2d
#SMILESを3D画像に変換
echo 'C(C1C(C(C(C(O1)O)O)O)O)O' | obabel -i smi -o png -O out5.png --gen3D

SMILESをPNG画像に変換

次に、SMILESをPDB/PDBQT形式に変換します。

#SMILESをPDB形式に変換
obabel -:'C(C1C(C(C(C(O1)O)O)O)O)O' -o pdb -O glucose.pdb --gen3D

#SMILESをPDBQT形式に変換
obabel -:'C(C1C(C(C(C(O1)O)O)O)O)O' -o pdbqt -O glucose.pdbqt --gen3D

#SMILESをmol2形式に変換
obabel -:'C(C1C(C(C(C(O1)O)O)O)O)O' -o mol2 -O glucose.mol2 --gen3D

#pymolでPDBファイルを可視化
pymol glucose.pdb

pymolで開くと、glucoseの3D構造が下図にように見えます。

pymolでPDBファイルを可視化

Open-Babelの関連コマンドについて

続いて、Open-Babelの関連コマンドについて紹介します。

まず、obenergyコマンドは、分子のエネルギーを計算します。

#GAFFによるエネルギー計算
obenergy -ff GAFF -v glucose.pdb 
#...
#E N E R G Y
#
#     TOTAL BOND STRETCHING ENERGY =    2.055 kJ/mol
#     TOTAL ANGLE BENDING ENERGY =   15.645 kJ/mol
#     TOTAL TORSIONAL ENERGY =    9.809 kJ/mol
#     TOTAL IMPROPER-TORSIONAL ENERGY =    0.000 kJ/mol
#     TOTAL VAN DER WAALS ENERGY =   31.348 kJ/mol
#     TOTAL ELECTROSTATIC ENERGY =   -7.801 kJ/mol
#
#TOTAL ENERGY =   51.056 kJ/mol

obpropコマンドは、標準的な分子特性を出力します。

obprop glucose.pdb 
#name             glucose.pdb 1
#formula          C6H12O6
#mol_weight       180.156
#exact_mass       180.063
#canonical_SMILES OC[C@H]1O[C@H](O)[C@@H]([C@@H]([C@@H]1O)O)O  
#
#InChI            InChI=1S/C6H12O6/c7-1-2-3(8)4(9)5(10)6(11)12-2/h2-11H,1H2/t2-,3-,4-,5-,6+/m1/s1
#
#num_atoms        24
#num_bonds        24
#num_residues     1
#num_rotors       1
#sequence         UNL
#num_rings        1
#logP             -3.2214
#PSA              110.38
#MR               35.736
#$$$$

obminimizeコマンドは、形状を最適化し、分子のエネルギーを最小になるように計算します。 また、obconformerコマンドは、低エネルギーコンフォーマーを生成します。

#GAFFによる構造 & エネルギー最適化: 2500計算がdefault 
obminimize -n 2500 -ff GAFF glucose.pdb > glucose_obm.pdb

#pymolで可視化
pymol glucose.pdb glucose_obm.pdb

#Monte Carlo searchによりランダム構造を作製した後に最も低いエネルギー状態を選択
#250個のランダム構造の生成、100 stepsの構造最適化
obconformer 250 100 glucose.pdb > glucose_obc.pdb

#pymolで可視化
pymol glucose.pdb glucose_obc.pdb

glucose.pdb と glucose_obc.pdbの重ね合わせ結果

計算前後の結果を重ね合わせていますが、ほとんど構造は変わってませんね。

PubChemからの化合物の情報・構造データの取得

PubChemは、国立生物工学情報センター(NCBI)によって維持管理されている、化学分子データベースの1つです。化合物情報の収録数は、確実に、世界一位でしょうね。

今回、PubChemから、「薬剤・薬物情報」に関する化合物の情報や構造をダウンロードします。 それでは、PubChemのWebページに訪問します。

これが、PubChemのホーム画面です。そこで、検索窓の下にある、「Browse Data」に進みます。

「薬剤・薬物情報」のデータを収集するため、「Drug and Medication Information」を選択します。 各自、必要に応じて、別カテゴリーを選択してください。化学物質数としては、約1.8万種類が収録されています。

続いて、右側のダウンロードのタブをクリックして、csv形式とsdf形式のファイルをそれぞれダウンロードします。ダウンロード後に、PubChem_Drug_Medication_Information.csvPubChem_Drug_Medication_Information.sdfという名前をつけて、作業ディレクトリ内に保存しました。

Rで、PubChem化合物データを読み込み

それでは、PubChemの化合物データ、csvファイルをR環境で読み込みます。 ここでは、readrパッケージのread_csvを使います。

#csv読み込み
PubChem <- readr::read_csv("PubChem_Drug_Medication_Information.csv", show_col_types = FALSE)

#表示
head(PubChem)
# A tibble: 6 × 24
#    cid cmpdname  cmpds…¹    mw mf    polar…² compl…³ xlogp
#  <dbl> <chr>     <chr>   <dbl> <chr>   <dbl>   <dbl> <chr>
#1     1 Acetylca… Acetyl… 203.  C9H1…    66.4     214 0.400
#2     2 1-Propan… 14992-… 204.  C9H1…    63.6     219 -0.3…
#3     6 1-Chloro… 1-chlo… 203.  C6H3…    91.6     224 2.300
#4    11 1,2-Dich… 1,2-di…  99.0 C2H4…     0         6 1.500
#5    34 2-Chloro… 2-chlo…  80.5 C2H5…    20.2      10 -0.1…
#6    38 2-Dehydr… 2-dehy… 146.  C6H1…    74.6     159 -0.1…
# … with 16 more variables: heavycnt <dbl>,
#   hbonddonor <dbl>, hbondacc <dbl>, rotbonds <dbl>,
#   inchi <chr>, isosmiles <chr>, inchikey <chr>,
#   iupacname <chr>, meshheadings <chr>, annothits <chr>,
#   annothitcnt <dbl>, aids <chr>, cidcdate <dbl>,
#   sidsrcname <chr>, depcatg <chr>, annotation <chr>, and
#   abbreviated variable names ¹<200b>cmpdsynonym, ²<200b>polararea, …
# ℹ Use `colnames()` to see all variable names

#列名
colnames(PubChem)
# [1] "cid"          "cmpdname"     "cmpdsynonym" 
# [4] "mw"           "mf"           "polararea"   
# [7] "complexity"   "xlogp"        "heavycnt"    
#[10] "hbonddonor"   "hbondacc"     "rotbonds"    
#[13] "inchi"        "isosmiles"    "inchikey"    
#[16] "iupacname"    "meshheadings" "annothits"   
#[19] "annothitcnt"  "aids"         "cidcdate"    
#[22] "sidsrcname"   "depcatg"      "annotation"  

1列目にcid、2列目にcmpdname、3列目にcmpdsynonym、8列目にxlogp、14列目にisosmiles、などの情報が含まれています。

「gluc」あるいは「glyc」を含む化合物名を検索する

glucoseの一部の「gluc」あるいは「glyc」を使って、3列目のcmpdsynonym内を検索して、化合物を探します。

#「gluc|glyc」でcmpdsynonym列を検索
PubChem0 <- PubChem[grepl("gluc|glyc", PubChem$cmpdsynonym),]

#cmpdname表示
head(PubChem0$cmpdname)
#[1] "2-Chloroethanol"   "Ethylene Glycol"   "Betaine"           "Trimethyl glycine"
#[5] "2,3-Butanediol"    "Cellobiose"  

#行列数
dim(PubChem0)
#[1] 1361   24

「gluc」or「glyc」で検索した結果、1361個の化合物がヒットしました。

ImageMagickを用いて、ヒットした化合物の2D画像を作成する

ここでは、ヒットした1361個の化合物のSMILESをもとに、2D画像(PNG)に変換します。

#SMILES情報
smiles <- PubChem0$isosmiles

#表示
head(smiles)
#[1] "C(CCl)O"                                    
#[2] "C(CO)O"                                     
#[3] "C[N+](C)(C)CC(=O)[O-]"                      
#[4] "C[N+](C)(C)CC(=O)O"                         
#[5] "CC(C(C)O)O"                                 
#[6] "C(C1C(C(C(C(O1)OC2C(OC(C(C2O)O)O)CO)O)O)O)O"

#2D画像に変換
for(n in 1:length(smiles)){
#n <- 1
a <- paste0("obabel -:'", smiles[n], "' -o png -O gluc_out_", formatC(n, width = 2, flag = "0"), ".png --gen2D")
#実行
system(a)
}

#ImageMagickを使った画像結合
system("montage -tile 15x15 -geometry 100% gluc_out_*.png gluc_out.png")

以下が、作成した化合物構造の画像です。

2D変換画像(1)

2D変換画像(2)

2D変換画像(3)

検索された化合物構造(sdf)をPyMolで可視化する

"ついで"くらいの内容ですが、ターミナルを起動して、pymolコマンドでsdfファイルが開いてみます。

pymol PubChem_Drug_Medication_Information.sdf

まとめ

PubChemからの化合物の情報・構造の取得方法とか、Open-BabelやPyMolコマンドについての使い方とかについて解説しました。

この内容は、主に、ドッキングシミュレーション用の下準備ですので、次回に続きます。。。

関連資料

skume.net

github.com

openbabel.org

future-chem.com

qiita.com

*1:以前は、babelだったような気がしますが、obabelに名前が変わったようですね。