R言語による電子カルテデータの二次利用

~R言語初心者がデータ処理を楽しめるように基本的内容中心のサイトです~

Rからopencvを使ってみる。

opencv使いたいときは不慣れなpython使ってましたが、いつの間にかRからopencvを利用するパッケージがでてました。できることは限られていますが、簡単に利用できるという意味ではpythonよりとっつきやすいと思います。

github.com

インストール(Windows

devtools::install_github("ropenscilabs/opencv")

これだけです。

画像の読み込み、出力

ocv_read(path)で読み込みます。出力は、オブジェクト名をそのまま実行してRstudioのViewerペインに出力するか、ocv_displayで別ウインドウに出力できます。

library(opencv)
child = ocv_read("child.jpg")
child
ocv_display(child)

f:id:r_beginner:20180919140613j:plain

画像の情報はocv_info(image)で確認できます。

> ocv_info(child)
$width
[1] 367

$height
[1] 465

$channels
[1] 3

画像の書き出し

ocv_write(image, path)で書き出せます。拡張子もjpg, png, bmp等いけました。

ocv_write(child, "hogehoge.jpg")
ocv_write(child, "hogehoge.png")
ocv_write(child, "hogehoge.bmp")

顔検出

もちろん画像ファイルの読み書きはmagickパッケージや他のパッケージでもできますが、これはopencvを使えるので、読み込んだ画像から、簡単に顔検出できます。

ocv_face(image)だけです。

ocv_face(child)

f:id:r_beginner:20180919141634j:plain

その他のフィルター

いくつかフィルターが準備されているようです。

ocv_edges(child)
ocv_hog(child)
ocv_markers(child)
ocv_sketch(child)
ocv_stylize(child)

f:id:r_beginner:20180919151417p:plain

webカメラの利用

おそらく僕にとって、これが一番有用な気がします。ちょっとパソコンいじりながらサンプル画像欲しい時、webカメラから簡単に画像撮れちゃいます。

img = ocv_camera()
ocv_write(img, "drone.jpg")

f:id:r_beginner:20180919142757j:plain

もちろん動画も出力できます。ocv_video関数を用います。先程のフィルターを引数に動画出力できるようです。

ocv_video(ocv_face)
ocv_video(ocv_edges)
ocv_video(ocv_blur)
ocv_video(ocv_hog)
ocv_video(ocv_markers)
ocv_video(ocv_mog2)
ocv_video(ocv_sketch)
ocv_video(ocv_stylize)

ocv_edgesのサンプル
f:id:r_beginner:20180919151937g:plain
ocv_sketchのサンプル
f:id:r_beginner:20180919174829g:plain
ocv_stylizeのサンプル
f:id:r_beginner:20180919174856g:plain

こまかい設定するなら、今のところpythonで書いたほうが良いと思いますが、短いコードでwebカメラから画像を取り込み、簡単に加工するなら、このパッケージがオススメです。

環境

> sessionInfo()
R version 3.4.0 (2017-04-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=Japanese_Japan.932  LC_CTYPE=Japanese_Japan.932   
[3] LC_MONETARY=Japanese_Japan.932 LC_NUMERIC=C                  
[5] LC_TIME=Japanese_Japan.932    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] opencv_0.1

loaded via a namespace (and not attached):
 [1] httr_1.2.1      compiler_3.4.0  magrittr_1.5    R6_2.2.2        tools_3.4.0    
 [6] withr_2.1.2     curl_2.6        yaml_2.1.19     Rcpp_0.12.18    memoise_1.1.0  
[11] git2r_0.18.0    digest_0.6.12   devtools_1.13.5

JAB-HCCのshinyアプリ

2015年、虎の門病院肝臓センターからこんな報告がありました。

本邦における B 型慢性肝疾患からの肝発癌予測リスクスコアモデル(Japanese risk estimations of HBV-related HCC:JAB-HCC)の作成
https://www.jstage.jst.go.jp/article/kanzo/56/9/56_477/_pdf

Cox 比例ハザードモデルを用いて、リスクスコアモデルを作成したというお話です。抗ウイルス療法無治療のB型慢性肝疾患症例1143例で検討されています。これだけの症例をしっかりデータ取れるのは、さすが虎ノ門です。古い症例はHBV-DNA測定系が違うはずですが、保存血清で全症例に現行のリアルタイムPCR方で再測定した結果を用いているとのこと…羨ましいかぎりです。

肝発癌に寄与する因子として抽出された,年齢,性別,肝硬変の有無,ALT 値,
AFP 値,血小板数,HBeAg の有無,HBVDNA 量の計8 因子は、各項目の重み付けを行い、点数の総和を検査するだけで、リスクを判定することができます。

患者さんに説明する際にも、核酸アナログを内服するリスク、内服しないリスクを説明しやすくなりとても重宝しておりました。たしかどこかの製薬会社のパッフレットにも早見表のようなものがあった気がします。ところが先日患者さんに説明しようとした際に、あれ!スコア表が無いぞ…汗
文献が見つかったので良かったのですが、資料を探す暇もおしいので、shinyアプリにしておきました。当院はshiny-severにアップしてあるので、ブラウザのお気に入りから、すぐ使えます。

f:id:r_beginner:20180721143459j:plain

shinyを勉強するのに参考になればと思い、汚いコードですが晒しておきます。すこし直せばいろいろなスコア計算のアプリができるので、よく使うものは自分用にスコア計算アプリを作ってみてはどうでしょうか。

library(shiny)
library(shinythemes)

ui <- fluidPage(theme = shinytheme("flatly"),
                titlePanel("JAB-HCC(Japanese risk estimations of HBV-related HCC)"),
                fluidRow(
                  column(2,
                         numericInput("age",
                                      label = h4("年齢:"), 
                                      value = 50)
                  ),
                  column(2,
                         radioButtons("gender",
                                      label = h4("性別:"),
                                      c("男性" = "1","女性" = "2"))
                  ),
                  column(2, 
                         radioButtons("LC_JAB", 
                                      label = h4("肝硬変"), 
                                      choices = list("無し" = 0, "有り" = 4),
                                      selected = 0)
                  ),
                  column(2,numericInput("Plt", 
                                        label = h4("Plt"),
                                        value = 25,
                                        step=1)
                  ),
                  column(2,numericInput("ALT", 
                                        label = h4("ALT"),
                                        value = 35,
                                        step=1)
                  )
                ),
                fluidRow(
                  column(2,
                         radioButtons("AFP_JAB", 
                                      label = h4("AFP"), 
                                      choices = list("20ng/ml未満" = 0, "20mg/ml以上" = 2),
                                      selected = 0)
                  ),
                  column(2,
                         radioButtons("HBeAg_JAB", 
                                      label = h4("HBe抗原"),
                                      choices = list("陰性" = 0, "陽性" = 3),
                                      selected = 0)
                  ),
                  column(3,
                         radioButtons("HBVDNA_JAB", 
                                      label = h4("HBV-DNA量"), 
                                      choices = list("5.0log copies/ml未満" = 0, "5.0log copies/ml以上" = 2),
                                      selected = 0)
                  )
                ),
                fluidRow(style="background-color:#fafafa;",
                         column(12, 
                                h4(textOutput("text_JABHCC"))
                         )
                )
)

server <- function(input, output) {
  output$text_JABHCC <- renderText({ 
    gender <- as.numeric(input$gender)
    if(gender == 1){ 
      genderJAB <- 4       # male
    } else if(gender == 2){ 
      genderJAB <- 0       #female
    }
    age <- as.numeric(input$age)
    if(age <= 44){
      ageJAB <- 0
    } else if(age >= 45 & age <= 49){
      ageJAB <- 3
    } else if(age >= 50 & age <= 54){
      ageJAB <- 5
    } else if(age >= 55){
      ageJAB <- 6
    }
    LCJAB <- as.numeric(input$LC_JAB)
    ALT <- as.numeric(input$ALT)
    if(ALT < 45){
      ALTJAB <- 0
    } else if(ALT >= 45){
      ALTJAB <- 1
    }
    AFPJAB <- as.numeric(input$AFP_JAB)
    Plt <- as.numeric(input$Plt)
    if(Plt >= 15){
      PltJAB <- 0
    } else if(Plt < 15){
      PltJAB <- 2
    }
    HBeAgJAB <- as.numeric(input$HBeAg_JAB)
    HBVDNAJAB <- as.numeric(input$HBVDNA_JAB)
    JAB_score <- genderJAB + ageJAB + LCJAB + ALTJAB + AFPJAB + PltJAB + HBeAgJAB + HBVDNAJAB
    if(JAB_score <= 6){
      comment_JAB <- c("低リスク群:累積10年発癌率  0.6%")
    } else if(JAB_score >= 7 & JAB_score <= 10){
      comment_JAB <- c("中リスク群:累積10年発癌率  2.2%")
    } else if(JAB_score >= 11 & JAB_score <= 15){
      comment_JAB <- c("高リスク群:累積10年発癌率 18.8%")
    } else if(JAB_score >= 16 & JAB_score <= 24){
      comment_JAB <- c("超高リスク群:累積10年発癌率 61.5%")
    }
    paste("JAB_score :", JAB_score,", ", comment_JAB)
  })
}

shinyApp(ui = ui, server = server)

ggplot2で臨床経過図を、簡単に作成する

はじめに

研修医の頃は、学会発表等で症例の経過図を作らされたものです(パワポで)。カンファレンスでも経過図使って上級医に説明したり、何十回作ったかわかりません(涙)。

こういうやつ↓

f:id:r_beginner:20180623131148j:plain

通常、バイタルデータや血液データをエクセルで入力してプロットし、グラフ画像を並べて配置。グラフの上には使用した薬剤の経過を図示して、プレゼンすることが多いかと思います。
もちろんこだわりの経過図ができると満足感はありますが、ちょっとした経過図は簡単に作成したいものです。

そこで、あまりこだわる必要の無い経過図は、なるべく自動化しましょう。というのが今回のブログです。

サンプルデータの準備

1. 薬剤使用歴
2. 体重の経過
3. 肝機能(ALT)の経過

今回は、適当に作ったサンプルデータをダウンロードしてプロットしてみます。実際は、エクセル等でCSVファイルを作って、read.csv等で読み込んで使うことになるかと思います。

library(RCurl)
url <- getURL("https://raw.githubusercontent.com/Algo1970/EHR_data/master/drug_dataset.csv")
Drug_df <- read.csv(text = url, header = TRUE)
Drug_df

f:id:r_beginner:20180623135854j:plain

このような横長?データが出力されているかと思います。
プロット用に縦長データに変形します。今回はtidy::gatherを使いました。あとでプロットするときのために日付はDate型にしておきます。

Drug_df_long = tidyr::gather(Drug_df, key="category", value = "date", start_date, end_date)
Drug_df_long$date = as.Date(Drug_df_long$date)
Drug_df_long

f:id:r_beginner:20180623135958j:plain

同様に、体重、肝機能のデータも落としてきます。

url <- getURL("https://raw.githubusercontent.com/Algo1970/EHR_data/master/BW_dataset.csv")
BW_df <- read.csv(text = url, header = TRUE)
BW_df$date = as.Date(BW_df$date)
head(BW_df)

f:id:r_beginner:20180623140252j:plain

url <- getURL("https://raw.githubusercontent.com/Algo1970/EHR_data/master/ALT_dataset.csv")
ALT_df <- read.csv(text = url, header = TRUE)
ALT_df$date = as.Date(ALT_df$date)
head(ALT_df)

f:id:r_beginner:20180623140317j:plain

これで準備は整いました。3つのサンプルデータは、練習のためデータの開始日をあえてずらしてあります。

プロット

シンプルに3つのプロットを並べてみると、いろいろ問題点が見えてきます。

library(ggplot2)
library(gridExtra)
# drug_plot
p1 = ggplot(Drug_df_long, aes(x=date, y=drug_name)) + geom_line()
# BW_plot
p2 = ggplot(data = BW_df, aes(date, BW)) + geom_line()
# ALT_plot
p3 = ggplot(data = ALT_df, aes(date, ALT)) + geom_line()
# plotの配置
grid.arrange(p1, p2, p3, layout_matrix = matrix(1:3, nrow=3))

f:id:r_beginner:20180623143425j:plain

問題点
  • 薬剤名の文字数が多いので、薬剤プロットが右にずれる
  • データの開始日が違うので、日付がずれる

いろいろ方法はあるのかもしれませんが、時間もなかったので薬剤名、体重、ALT等y軸のラベルは削除し、geom_textで表示します(y軸のラベルの文字幅の影響が少なければ、そのままでも良いかもしれません)。
日付のズレは、3つのデータセットの日付のminとmaxを求めて、x軸をxlim(最小値, 最大値)で指定しておきます。

# 日付調整
library(dplyr)
Drug_min_date = Drug_df_long$date %>% min()
BW_min_date = BW_df$date %>% min()
ALT_min_date = ALT_df$date %>% min()
minDate = min(Drug_min_date, BW_min_date, ALT_min_date)

Drug_min_date = Drug_df_long$date %>% max()
BW_min_date = BW_df$date %>% max()
ALT_min_date = ALT_df$date %>% max()
maxDate = max(Drug_min_date, BW_min_date, ALT_min_date)

p1 = ggplot(Drug_df_long, aes(x=date, y=drug_name)) + 
  geom_line() + 
  xlim(minDate, maxDate) + 
  labs(y= "", title = "drug") +
  theme(axis.text.y = element_blank())
p2 = ggplot(data = BW_df, aes(date, BW)) + 
  geom_line() + 
  xlim(minDate, maxDate) + 
  labs(y= "", title = "BW") +
  theme(axis.text.y = element_blank())
p3 = ggplot(data = ALT_df, aes(date, ALT)) + 
  geom_line() + 
  xlim(minDate, maxDate) + 
  labs(y= "", title = "ALT") +
  theme(axis.text.y = element_blank())
grid.arrange(p1, p2, p3, layout_matrix = matrix(1:3, nrow=3))

f:id:r_beginner:20180623145821p:plain

これで日付、グラフのズレがなくなりました。あとは、薬剤名、数値をgeom_textで貼り付けて、お化粧するだけです。

サンプルプロット1(グレイ)

# plot_gray
p1 = ggplot(Drug_df_long, aes(x=date, y=drug_name)) + 
  geom_line(size=10, alpha = 0.4) +
  geom_text(aes(label = drug_name), color="black", size = 6, check_overlap = T) +
  xlim(minDate, maxDate) + 
  labs(x = "", y= "", title = "Drug") +
  theme_minimal() + 
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),
        axis.text.x = element_blank(), 
        axis.text.y = element_blank()) 
p2 = ggplot(data = BW_df, aes(date, BW)) + 
  geom_line(color = "black", size = 3, alpha = 0.3) + 
  geom_point(color = "black", size = 3.5, alpha = 0.2) +
  geom_text(aes(label = BW), color="black", size = 6, check_overlap = T) +
  xlim(minDate, maxDate) + 
  labs(x = "", y= "", title = "BW") +
  theme_minimal() + 
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),
        axis.text.x = element_blank(), 
        axis.text.y = element_blank()) 
p3 = ggplot(data = ALT_df, aes(date, ALT)) + 
  geom_line(color = "black", size = 3, alpha = 0.3) + 
  geom_point(color = "black", size = 3.5, alpha = 0.2) +
  geom_text(aes(label = ALT), color="black", size = 6, check_overlap = T) +
  xlim(minDate, maxDate) + 
  labs(x = "", y= "", title = "ALT") +
  theme_minimal() + 
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),
        axis.text.x = element_text(size = 15), 
        axis.text.y = element_blank()) 
grid.arrange(p1, p2, p3, layout_matrix = matrix(1:3, nrow=3))

f:id:r_beginner:20180623151819p:plain

サンプルプロット2(カラー)

配色はお好みで…

# plot_color
p1 = ggplot(Drug_df_long, aes(x=date, y=drug_name, colour = drug_name)) + 
  geom_line(size=10, alpha = 0.4) +
  geom_text(aes(label = drug_name), size = 6, check_overlap = T) +
  scale_colour_discrete(guide=FALSE) + 
  xlim(minDate, maxDate) + 
  labs(x = "", y= "", title = "Drug") +
  theme_minimal() + 
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),
        axis.text.x = element_blank(), 
        axis.text.y = element_blank()) 
p2 = ggplot(data = BW_df, aes(date, BW)) + 
  geom_line(color = "orange", size = 3, alpha = 0.5) + 
  geom_point(color = "orange", size = 3.5, alpha = 0.2) +
  geom_text(aes(label = BW), color="black", size = 6, check_overlap = T) +
  xlim(minDate, maxDate) + 
  labs(x = "", y= "", title = "BW") +
  theme_minimal() + 
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),
        axis.text.x = element_blank(), 
        axis.text.y = element_blank()) 
p3 = ggplot(data = ALT_df, aes(date, ALT)) + 
  geom_line(color = "darkblue", size = 3, alpha = 0.3) + 
  geom_point(color = "darkblue", size = 3.5, alpha = 0.2) +
  geom_text(aes(label = ALT), color="black", size = 6, check_overlap = T) +
  xlim(minDate, maxDate) + 
  labs(x = "", y= "", title = "ALT") +
  theme_minimal() + 
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),
        axis.text.x = element_text(size = 15), 
        axis.text.y = element_blank()) 
grid.arrange(p1, p2, p3, layout_matrix = matrix(1:3, nrow=3))

f:id:r_beginner:20180623152600p:plain

私はいつも、最上段が薬剤経過で、時々症状の経過を加え、二段から三段、四段組ぐらいの経過図が多いので、関数化してサッとプロットできるようにして使用しています。
ホントは、汎用的な関数にしたいなと思っているのですが、今は追い込まれているので今度にします。

IBDの難治例とか、原因不明の慢性肝炎、多剤使用している薬剤性肝障害等、経過図を書くと病態がわかりやすくなるので、すこしでも参考になればとブログを書いてみました。

DiagrammeR 〜RでGraphvizを使う~

パワポフローチャートや、ネットワーク図を作ると、ノードやエッジの位置が微妙にずれて、面倒だなと感じる人はいませんか。そんな時は、Graphvizを使用しましょう。
Graphvizを使うと、DOT言語で書かれたグラフを画像に出力できます。R言語では、DiagrammeRのgrViz関数で、DOT言語のテキストを画像に出力します。

目次:

DiagrammeR::grViz()

DiagrammeRではgrViz関数をつかって、DOT言語で記述されたグラフ構造を出力します。
簡単なサンプルです。grViz関数の引数部分(ダブルクォーテーションの中)がDOT言語です。

library(DiagrammeR)
grViz("
      digraph test {
        A -> B
      }
      ")

出力はこうなります。
f:id:r_beginner:20180310183017j:plain

Graphviz本家サイトにも沢山のサンプルがありますが、実際思ったとおりのグラフを出力しようと思うと細かい設定で詰まることが多く、結局ググってサンプルコードを探してくることが多いです。ここでは、自分がよく使う設定等を補足しながら、Graphvizの使い方をまとめておきます。

Graphvizサイト: Graphviz - Graph Visualization Software


DOT言語

DOT は、プレーンテキストを用いてデータ構造としてのグラフを表現するための、データ記述言語の一種である。

DOT言語 - Wikipedia

DOTの構造

digraph 名前 {}

digraphの名前は、予約語を指定するとエラーがでます。Rstudioでは.gv/.dot拡張子のファイルは、シンタックスハイライトが使えるので、予約語かどうかが分かりやすくて良いと思います。

graph, node , edgeについてそれぞれ指定していきます。

  • graph [ 属性=値, ...]
  • node [ 属性=値, ...]
  • edge [ 属性=値, ...]

と記載していきます。

digraph test {
  graph[rankdir = LR, label ="fig. 1"]
  node [shape = box] A; B;
  edge[color = red, arrowsize = 1.5, arrowhead = normal] A -> B
}

RstudioでDOT言語

f:id:r_beginner:20180310202320j:plain
上記のようにgrViz関数の引数としてDOT言語のテキストを記述するサンプルがよく書かれていますが、これだとdigraph以下がハイライトされません。長いコードではタイポしやすくなるので、.gvまたは.dot拡張子で外部ファイルとしておいた方がシンタックスハイライトを利用できるので良いかと思います。Rstudioでは、.gv(.dot)ファイルは、sourceペイン右上にプレビューボタンがでて、ボタンを押すとgrViz関数を呼び出して自動でRstudioのviewerペインに出力してくれます。test.dotファイルなら、DiagrammeR::grViz("test.dot")が実行されます。

f:id:r_beginner:20180310184155p:plain


Graphviz Attributes

http://204.178.9.49/content/attrs

Graph属性

サンプル

digraph graph_attribute {
  graph[rankdir = LR, 
        label ="fig. 1",
        labelloc = t # t, b
        fontsize = 10, 
        fontcolor = red,
        bgcolor = darkgreen,
        nodesep = 0.1, 
        ranksep = 0.1]
}

rankdir : グラフ全体の方向をTB(top -> bottom),LR(left -> right)等変更。

label : ラベル名。

labelloc : ラベルの位置指定。t(top), b(bottom)で指定。

bgcolor : バックグラウンドカラー。

nodesep : ノードの間隔。

ranksep : ランクの間隔。

f:id:r_beginner:20180310200309p:plain

Node属性

color属性
digraph node_color {
  node[style = "filled", color = IndianRed] IndianRed;
}

f:id:r_beginner:20180310222947j:plain

  • カラーサンプル

f:id:r_beginner:20180310201041j:plain

shape属性
digraph node_shape {
  node[shape = box] box;
}
  • shapeサンプル

f:id:r_beginner:20180310201209p:plain

style属性
digraph node_style {
  node[shape = box]
  node[style = solid]
  A
  node[style = dashed]
  B
  node[style = dotted]
  D
  node[style = bold]
  E
  node[style = filled]
  F
  node[style = striped, fillcolor = "Yellow1:Yellow2:Yellow3:Yellow4"]
  G
  node[shape = circle , style = "dashed, wedged", fillcolor = "Tomato1:Tomato2:Tomato3:Tomato4"]
  H
}
  • スタイルサンプル

f:id:r_beginner:20180310201411p:plain

rank属性
digraph node_rank {
  groupA -> groupB -> groupC
  A; B; C; D; E; F; G; H; I
  {rank = same; groupA; A; B; C;}
  {rank = same; groupB; D; E; F;}
  {rank = same; groupC; G; H; I}
}

f:id:r_beginner:20180310203055p:plain

label属性

labelの値にはHTMLっぽい記述をすることが出来ます。

digraph test_graph {
  node[shape = rect, color = black, label = <<I>italic</I>>] A 
  node[label = <10<sup>2</sup>>] B
}

ただし、<>で全体を囲む必要があるみたいです。すべてのタグが使えるわけでも無いみたい…難しい。

特殊な文字は、node[label = "&文字列;"]みたいな感じで出力できるものもあります。

digraph test_graph {
  node[shape = box]
  node[label = "&#931; &#928; &#945; &#946; &#947; &#948; &#949;"] A
  node[label = "&#952; &#954; &#955; &#956; &#966; &#969;"] B
  node[label = "&#9824; &#9825; &#9826; &#9827; &#9834; &#12306; "] C
}

f:id:r_beginner:20180310214949j:plain

ギリシャ文字
【みんなの知識 ちょっと便利帳】使いたいときの HTML特殊文字 & 機種依存文字 - ギリシャ文字

image属性

image属性でファイルパスを指定すると画像を出力できるはずだが、僕の環境のDiagrammeR::grviz()では下記の.dotファイルはうまく出力できませんでした。

digraph ramen {
  rankdir = LR
  node[penwidth = 0, 
       fontname = helvetica,
       labelloc = t, 
       fontsize = 30, 
       fontcolor = darkgreen]
  node[image = "img/sio.jpg"] sio;
  node[image = "img/syouyu.jpg"] syouyu;
  sio -> syouyu
}

いつもはUbuntu16.04にRstudio severをインストールして使用しているので、

$ sudo apt install graphviz

Graphvizをインストールして。
.dotファイルを、Terminalからコマンドで出力して対応

$ dot -Tpng ramen.dot  -o ramen.png

f:id:r_beginner:20180310210333p:plain

最近のRstudioはTerminalペインもあり、気軽にコマンド入力もできるので、DOTファイルからそのまま出力して今回はごまかしました。(DiagrammeRからできるひと教えてください…)

Edge属性

arrowhead属性
digraph edge_arrowhead {
  edge[arrowhead = diamond] A -> B;
}

arrowheadサンプル
f:id:r_beginner:20180310203552p:plain

  • arrowhead名の前に"o"をつけると中抜けになります。
  • "r","l"をつけると、左右半分のarrowheadになります。
  • arrowhead名をつづけて書くと、arrowheadを繋げて出力できます。
dir, arrowsize, color, penwidth属性
digraph edge_arrowhead {
  edge[dir= both, arrowsize = 0.5, color = red, penwidth = .5] A -> B;
}

dir, size, color, penwidthサンプル
f:id:r_beginner:20180310203721p:plain

port属性
digraph edge_arrowhead {
  edge[tailport = n] A -> B;
}

portサンプル
f:id:r_beginner:20180310203924p:plain

Subgraph

digraph subgraph_label {
  rankdir = TB
  subgraph cluster0{
    A -> B 
    label = "group0"
    {rank = same; A; B;}
  }
  subgraph Cluster1{
    C -> D -> E
    label = "group1"
    {rank = same; D; E;}
  }
  B -> C
}

subugraphでいくつかのnodeをグループ化できます。subgraph名は、小文字のcから始まるcluster**の場合に枠線がつきますが、その他の名前では枠が消えます。
f:id:r_beginner:20180310225609j:plain

subgraphからnode、nodeからsubgraph、subgraphからsubgraphへもedgeを繋ぐことができます。

digraph G {
  compound=true;
  subgraph cluster0 {
  b -> d;
  c -> d;
  }
  subgraph cluster1 {
  e -> g;
  e -> f;
  }
  b -> f [lhead=cluster1];
  d -> e;
  c -> g [ltail=cluster0, lhead=cluster1];
  c -> e [ltail=cluster0];
}

f:id:r_beginner:20180310230807j:plain
ちなみに、subgraphを重ねることはできないみたいです。


DOT言語で、どんなグラフも作成できるわけではないですが、何度か作り直しながら使用していくようなフローチャートや、ネットワーク図は、パワポで作るより修正が楽だと思います。

Enjoy!

環境

> sessionInfo()

## R version 3.4.3 (2017-11-30)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 16.04.4 LTS
## 
## Matrix products: default
## BLAS: /usr/lib/libblas/libblas.so.3.6.0
## LAPACK: /usr/lib/lapack/liblapack.so.3.6.0
## 
## locale:
##  [1] LC_CTYPE=ja_JP.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=ja_JP.UTF-8        LC_COLLATE=ja_JP.UTF-8    
##  [5] LC_MONETARY=ja_JP.UTF-8    LC_MESSAGES=ja_JP.UTF-8   
##  [7] LC_PAPER=ja_JP.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=ja_JP.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] DiagrammeR_0.9.2
## 
## loaded via a namespace (and not attached):
##  [1] Rcpp_0.12.15       pillar_1.1.0       compiler_3.4.3    
##  [4] RColorBrewer_1.1-2 influenceR_0.1.0   plyr_1.8.4        
##  [7] bindr_0.1          viridis_0.5.0      tools_3.4.3       
## [10] digest_0.6.15      jsonlite_1.5       viridisLite_0.3.0 
## [13] gtable_0.2.0       evaluate_0.10.1    tibble_1.4.2      
## [16] rgexf_0.15.3       pkgconfig_2.0.1    rlang_0.1.6       
## [19] igraph_1.1.2       rstudioapi_0.7     yaml_2.1.16       
## [22] bindrcpp_0.2       gridExtra_2.3      downloader_0.4    
## [25] dplyr_0.7.4        stringr_1.2.0      knitr_1.19        
## [28] htmlwidgets_1.0    hms_0.4.1          grid_3.4.3        
## [31] rprojroot_1.3-2    glue_1.2.0         R6_2.2.2          
## [34] Rook_1.1-1         XML_3.98-1.9       rmarkdown_1.9     
## [37] ggplot2_2.2.1      purrr_0.2.4        readr_1.1.1       
## [40] tidyr_0.8.0        magrittr_1.5       backports_1.1.2   
## [43] scales_0.5.0       htmltools_0.3.6    assertthat_0.2.0  
## [46] colorspace_1.3-2   brew_1.0-6         stringi_1.1.6     
## [49] visNetwork_2.0.3   lazyeval_0.2.1     munsell_0.4.3

Shinyアプリのテンプレートを簡単に作成してみる。

shinyアプリが盛り上がっています。僕の周りだけかもしれませんが…

R言語で便利な関数を作って、Rstudioで使用するのも良いのですが、時にはマウスで操作できるアプリを作りたくなる時もあります。そんな時Rには、shinyパッケージという簡単なアプリを作るパッケージが有ります。

ただアプリを作り始めて意外と面倒だと感じるのが、このshinyアプリの雛形づくりです。カッコの数があわなかったり、カンマが多かったり。アプリを作ると何度もエラーを吐かれます。(練習不足という話もありますが…)

そこで、簡単にshinyアプリのテンプレートを作成する、アプリを作成してみました。もちろんshinyアプリで…

ダウンロード

ここからzipファイルをダウンロードして使用してください。
GitHub - Algo1970/shinymaker

f:id:r_beginner:20170706203548p:plain

使用法

ダウンロード後、Rstudioからshinymakerフォルダのshinymakerプロジェクトを開いて下さい。 次にshinymaker.Rを実行します。shinymaker.R自体がshinyアプリですので、Run Appボタンを押して実行して下さい。


あくまでも個人使用のために作成したので、自分でよく使うUIやOutputコンテンツしか入れてありません。
雛形のテキストコードを貼り付けて、ui.Rとserver.Rのコードを自動作成するだけです。ですが…結構便利です。

起動後の画面は、こんな感じです。
f:id:r_beginner:20170706201111p:plain

画面を見ながら、タイトルつけたり、テーマを選択したり、入れたいパッケージをクリックしたり、UIコンテンツやoutoputコンテンツを選んだりして、最後にmake shinycodeボタンを押します。

これでワーキングディレクトリにshinyアプリ(ui.r/server.r)の入ったsampleフォルダが作成されます。
f:id:r_beginner:20170706202323p:plain
フォルダの中を覗くとui.Rとserver.Rができています。
f:id:r_beginner:20170706202412p:plain

どのようなコードが作成されたか確認するには、display codeボタンを押します。タブ内にコードが表示されました。
f:id:r_beginner:20170706202623p:plain

できたアプリを実行してみましょう。
f:id:r_beginner:20170706202911p:plain

ここまであっという間です。あとは、配置を変えたり、メインのコードを書くだけなので、気軽にshinyアプリが作れるようになりました。たくさん楽しいshinyアプリを作って、shinyサーバーに載せて楽しみましょう。

RでSQLserver(on Ubuntu16.04)への接続

現在当院で使用している電子カルテのデータベースは、MicrosoftSQLサーバーです。ハードの保守期間も過ぎたため、今回ハードの更新と、Windows10版のクライアントへの変更、サーバーも変更しました。
今までは、クライアントPC(windows7)にR・RstudioをインストールしSQLサーバーへの接続していましたが、他のクライアントPCからも同じ環境を使用できるようにRstudio serverで環境を作り直すことにします。

まず、ローカルネットワーク上にUbuntu実マシンを用意し、R環境とRstudio serverをインストール。いままでは、Windowsマシンからしか接続した経験がないので、UbuntuでのODBC接続の練習をしてみたいと思います。
自宅にSQLserverがないので、SQLserver2017 CTP2.1をubuntu16.04にインストールしてみます。CTPはCommunity Technology Previewで評価版のため使用制限もあります。なおこの評価版はUbuntu16.04、Ubuntu16.10で64bitが対応しているそうです。

kledgeb.blogspot.jp

SQLserverのインストー

練習環境ですのでUbuntu16.04の仮想マシンに構築します。
Ubuntu端末から下記シェルスクリプトを実行してください。

#!bin/sh

# install R
sudo sh -c "echo 'deb http://cran.ism.ac.jp/bin/linux/ubuntu xenial/' >> /etc/apt/sources.list"
gpg --keyserver keyserver.ubuntu.com --recv-key E084DAB9
gpg -a --export E084DAB9 | sudo apt-key add -
sudo apt-get update
sudo apt-get -y install r-base

# install Rstudio-server
sudo apt-get install gdebi-core
wget https://download2.rstudio.org/rstudio-server-1.0.143-amd64.deb
sudo gdebi rstudio-server-1.0.143-amd64.deb

# install RODBC
sudo apt-get install r-cran-rodbc

# install SQLserver
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
curl https://packages.microsoft.com/config/ubuntu/16.04/mssql-server.list | sudo tee /etc/apt/sources.list.d/mssql-server.list
sudo apt-get update
sudo apt-get install -y mssql-server
sudo /opt/mssql/bin/mssql-conf setup
# passwordを確認されるので、入力。

# install tools on Ubuntu
# curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - 
curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list | sudo tee /etc/apt/sources.list.d/msprod.list
sudo apt-get update 
sudo apt-get -y install mssql-tools unixodbc-dev

echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc

途中でパスワード入力後に、評価版のため153日の試用期間と表示されますが、テスト環境なので十分です。
f:id:r_beginner:20170611132312j:plain


Linuxクライアントからの接続

まずは先程インストールした、mssql-toolsを使って接続します。
sqlcmdコマンドが使えるようになっているので、

$ sqlcmd -S localhost -U SA -P '<YourPassword>'
$ sqlcmd -S <IP address> -U SA -P '<YourPassword>'

接続できたでしょうか

$ sqlcmd -S localhost -U SA -P '********'
1> 

このように出力されればOKです。

1> SELECT Name from sys.Databases;
2> GO
Name                                                                                                                            
--------------------------------------------------------------------------------------------------------------------------------
master                                                                                                                          
tempdb                                                                                                                          
model                                                                                                                           
msdb                                                                                                                            
testdb                                                                                                                          

(5 rows affected)
1> 

SELECT文でデータベース名が確認できたかと思います。

次にODBC接続の練習です。

$ sudo gedit /etc/odbcinst.ini

でODBCdriverを確認してみましょう。
f:id:r_beginner:20170611134506j:plain

次にODBC.iniの設定です。

$ sudo gedit /etc/odbc.ini

f:id:r_beginner:20170611134828j:plain
上記を参考に、ポート番号、ユーザー名、パスワード、データベース名等入力してください。 [ ] の中(今回はsqlserver)がDSN(Data Source Name)です。

準備ができいたら、ブラウザから IPaddress : 8787 でRstudio serverにログインします。
PackageタブのあるPaneでRODBCがインストールされているのも、一応確認してみてください。

あとは新規ファイルを作成し、下記コードをコピペします。

library(RODBC)
con <- RODBC::odbcConnect(dsn="sqlserver",uid="SA",pwd="********")
sqlQuery(con, "select name from sys.Databases;")

実行すると、コンソールにデータベース名が出力されます。

> sqlQuery(con, "select name from sys.Databases;")
    name
1 master
2 tempdb
3  model
4   msdb
5 testdb
> 
Windowsクライアントからの接続

まず、Windows PowerShellを使います。
f:id:r_beginner:20170611141213j:plain
OSの左下、検索窓に 'pow'と入力してみてください。
シェルが立ち上がったら、先程同様に

$ sqlcmd -S <IP address> -U SA -P '<YourPassword>'
1> SELECT Name from sys.Databases;
2> GO

とコマンド入力してみてください。
f:id:r_beginner:20170611142750j:plain
データベース名が出力されます。

次にODBCドライバーを使います。

f:id:r_beginner:20170611141213j:plain
OSの左下、検索窓に 'データ'と入力してみてください。

f:id:r_beginner:20170611141604j:plain
検索候補に現れた、ODBCデータソースを選択

f:id:r_beginner:20170611141724j:plain
追加ボタンを押して、
f:id:r_beginner:20170611141752j:plain
データソース名、サーバーのIPアドレスを入力
f:id:r_beginner:20170611141852j:plain
SQLサーバー認証のため、ログインID、パスワードを入力し、次へ。
f:id:r_beginner:20170611141957j:plain
test data sourceボタンを押すと、
f:id:r_beginner:20170611142032j:plain
テスト成功の文字が出て終了です。

これでRstudio-serverを使えば、全ての職場PCから電子カルテサーバーにRでアクセスできるはず…。


参考

shiny server環境構築(ubuntu16.04)

職場のみんなでshinyアプリが使えるようにshiny server環境を構築してみたいと思います。

www.rstudio.com

今回も練習用にUbuntu仮想マシンを用意しました。

まずR、shiny、shiny-server等インストールしましょう。

$ sudo apt-get -y install r-base
$ sudo su - \
-c "R -e \"install.packages('shiny', repos='https://cran.rstudio.com/')\""
$ sudo apt-get install gdebi-core
$ wget https://download3.rstudio.org/ubuntu-12.04/x86_64/shiny-server-1.5.3.838-amd64.deb
$ sudo gdebi shiny-server-1.5.3.838-amd64.deb

これでインストールは終了です。
ブラウザにlocalhost:3838と入力してみましょう。
f:id:r_beginner:20170427203415j:plain
こんな画面がでれば上手くいっていると思います。

rmarkdown packageもインストールしておきましょう。

$ sudo su - -c "R -e \"install.packages('rmarkdown', repos='http://cran.rstudio.com/')\""

ブラウザにhttp://localhost:3838/sample-apps/rmd/と入力すると、
f:id:r_beginner:20170427205401j:plain
上手く見えたでしょうか。

今度は自作shinyアプリを、動かしてみましょう。
f:id:r_beginner:20170427221723j:plain
/srv/shiny-server/sample-apps以下に自作ファイルを起きます。hello,rmdフォルダはサンプルで、もともとあるものです。
ここにsample0427フォルダを作成します。

ユーザーをrootグループに入れておきます。

$ sudo gpasswd -a <username> root

あとは作成したshinyファイルを入れるだけです。

$ mkdir sample0427
$ gedit ui.R
$ gedit server.R

でshinyファイルを作成しました。
ブラウザでlocalhost:3838/sample-apps/sample0427と入力してみましたが、エラーで動いていないようです。

$ sudo systemctl status shiny-server
$ sudo systemctl restart shiny-server

serverは動いているようですし、再起動してみましたが、うまくブラウザから見えない…

$ sudo chmod 777 ui.R
$ sudo chmod 777 server.R
$ sudo systemctl restart shiny-server

権限与えてみましたが、ダメ

パッケージが入っていない?ggplot2 packageを入れてみましょう。

$ sudo su - -c "R -e \"install.packages('ggplot2', repos='http://cran.rstudio.com/')\""

f:id:r_beginner:20170427213211j:plain

今度は上手く表示されました。パッケージが入っていないだけだったのですが、気づくのに少し時間がかかりました。とりあえずこれで自作アプリがshiny-serverで動く環境ができました。あとは時間のある時に、設定ファイルの勉強をしておけば良いかな。


参考