Rで解析:Shinyで習作2「プロットを保存」

Rの解析に役に立つ記事
スポンサーリンク

Shinyの習作、その2です。出力したワードクラウドをPNG形式での保存とデータをテーブルで表示する例です。

紹介コマンドをコピー後にRStudioを利用し「ui.R」と「server.R」を用意、メニューのRun Appの右側下矢印を選択後「Run External」でウェブブラウザで作動させるのがポイントです。そうしないと、PNG形式での保存がうまく動作しません。

RStudioの2022.12.0 Build 353。windows 10のR version 4.2.2で動作を確認しています。

スポンサーリンク

コマンドの紹介

詳細はコマンド、各パッケージのヘルプを確認してください。

ui.Rの内容

#ui.R
#可変レイアウト
shinyUI(fluidPage(
  #タイトルを指定
  titlePanel("PubMedでWordCloud"),
  #1行目:可変レイアウト
  fluidRow(plotOutput("WordCloud",  width = "100%")),
  #2行目:可変レイアウト
  fluidRow(
    #1列目
    column(2, textInput("QueryWord", "クエリ", "クエリを入力"),
           textInput("GetPaper", "取得論文数", "100"),
           actionButton("GoWordCloud", "ワードクラウドを作成")),
    #2列目
    column(3, sliderInput("CountWord", "単語出現数", min = 1, max = 20, value = 5, step = 1),
           #画像保存用のボタン
           downloadButton("image", "プロットをPNGで保存")),
    #2列目
    column(5, p("出現単語表"), dataTableOutput("table"))
  )
)
)

server.Rの内容

#server.R
#パッケージの読み込み
if (!require("easyPubMed")) {
  install.packages("easyPubMed")}
if (!require("tm")) {
  install.packages("tm")}
if (!require("wordcloud")) {
  install.packages("wordcloud")}
if (!require("tcltk")) {
  install.packages("tcltk")}

shinyServer(function(input, output) {
  
  #ui.Rからの入力の処理を調整するreactiveコマンド
  #QueryWordでPubMedを検索してタイトルを取得:GetWordCloudData処理
  GetWordCloudData <- reactive({
    #GoWordCloud&#12508;&#12479;&#12531;&#12434;&#25276;&#12377;&#12414;&#12391;isolate&#12467;&#12510;&#12531;&#12489;&#20869;&#12434;&#20966;&#29702;&#12375;&#12394;&#12356;
    input$GoWordCloud
    isolate(
      if("&#12463;&#12456;&#12522;&#12434;&#20837;&#21147;" == input$QueryWord){
        
      }else{
        
        #&#32080;&#26524;&#12398;&#21462;&#24471;
        ALL_Result <- get_pubmed_ids(input$QueryWord)
        GetResult <- fetch_pubmed_data(ALL_Result,
                                       retmax = input$GetPaper, format = "xml")
        
        #&#35542;&#25991;&#12479;&#12452;&#12488;&#12523;&#12434;&#21462;&#24471;
        TitleData <- unlist(xpathApply(GetResult, "//ArticleTitle", xmlValue))
        
        ###&#12486;&#12461;&#12473;&#12488;&#12510;&#12452;&#12491;&#12531;&#12464;&#12398;&#35373;&#23450;&#12289;&#12362;&#22909;&#12415;&#12395;&#21512;&#12431;&#12379;&#12390;&#12367;&#12384;&#12373;&#12356;#####
        CorMaster <- Corpus(DataframeSource(data.frame(TitleData))) #&#12467;&#12540;&#12497;&#12473;&#12398;&#20316;&#25104;
        CorMaster <- tm_map(CorMaster, stripWhitespace) #&#31354;&#30333;&#12398;&#21066;&#38500;
        CorMaster <- tm_map(CorMaster, removeNumbers) #&#25968;&#23383;&#12398;&#21066;&#38500;
        CorMaster <- tm_map(CorMaster, removePunctuation) #&#21477;&#35501;&#28857;&#12398;&#21066;&#38500;
        CorMaster <- tm_map(CorMaster, removeWords, stopwords("english")) #and, or&#31561;&#12398;&#21066;&#38500;
        TermVec <- DocumentTermMatrix(CorMaster) #&#12479;&#12540;&#12512;&#12510;&#12488;&#12522;&#12483;&#12463;&#12473;&#12398;&#38598;&#35336;
        ########
        
        ###&#21336;&#35486;&#35299;&#26512;&#32080;&#26524;&#12434;&#12487;&#12540;&#12479;&#12501;&#12524;&#12540;&#12512;&#21270;#####
        #&#21336;&#35486;&#12398;&#20986;&#29694;&#29575;&#12434;&#38598;&#35336;
        AnalyticsAllWords <- as.data.frame(apply(TermVec, 2, sum))
        AnalyticsAllWords <- cbind(rownames(AnalyticsAllWords), AnalyticsAllWords)
        #&#38500;&#21435;&#12375;&#12383;&#12356;&#21336;&#35486;&#12434;&#35373;&#23450;
        AnalyticsAllWords <- subset(AnalyticsAllWords,
                                    !(AnalyticsAllWords[, 1] %in% c("the", "this", "can", "thus", "these")))
        ########
        
      })
  })
  
  #&#20351;&#12356;&#22238;&#12375;&#12377;&#12427;&#12383;&#12417;&#12395;&#12527;&#12540;&#12489;&#12503;&#12525;&#12483;&#12488;&#29992;&#12398;&#12487;&#12540;&#12479;&#12399;&#38306;&#25968;&#12391;&#20966;&#29702;
  #&#12527;&#12540;&#12489;&#12503;&#12525;&#12483;&#12488;&#12434;&#20316;&#25104;:PlotWordCloud&#38306;&#25968;
  PlotWordCloud <- function(){
    
    #&#29702;&#35299;&#12375;&#12420;&#12377;&#12356;&#12424;&#12358;&#12395;GetWordCloudData&#20966;&#29702;&#12391;&#24471;&#12383;&#32080;&#26524;&#12434;AnalyticsAllWords&#12395;&#20195;&#20837;
    AnalyticsAllWords <- GetWordCloudData()
    #GetWordCloudData&#20966;&#29702;&#12398;&#32080;&#26524;&#12364;&#20309;&#12363;&#12354;&#12427;&#22580;&#21512;&#12395;&#12527;&#12540;&#12489;&#12503;&#12525;&#12483;&#12488;&#12434;&#20316;&#25104;
    if(is.null(AnalyticsAllWords) == FALSE){
      #GetWordCloudData&#20966;&#29702;&#12391;&#24471;&#12383;&#32080;&#26524;&#12363;&#12425;&#20986;&#29694;&#25968;&#12364;CountWord&#20197;&#19978;&#12434;&#25277;&#20986;
      AnalyticsWords <- subset(AnalyticsAllWords,
                               AnalyticsAllWords[, 2] >= input$CountWord)
      #&#20986;&#29694;&#22238;&#25968;&#12391;&#38477;&#38918;
      AnalyticsWords <- AnalyticsWords[order(AnalyticsWords[, 2], decreasing = TRUE),]
      #&#12487;&#12540;&#12479;&#21517;
      colnames(AnalyticsWords) <- c("&#21336;&#35486;", "&#20986;&#29694;&#22238;&#25968;")
      AnalyticsWords
    }else{}
  }
  
  #plotOutput&#12395;&#20986;&#21147;&#12377;&#12427;renderPlot&#12467;&#12510;&#12531;&#12489;
  #&#12527;&#12540;&#12489;&#12503;&#12525;&#12483;&#12488;&#12434;ui.R&#12398;WordCloud&#12395;&#20986;&#21147;:output$WordCloud&#20966;&#29702;
  output$WordCloud <- renderPlot({
    
    #GetWordCloudData&#20966;&#29702;&#32080;&#26524;&#12395;&#20309;&#12363;&#12354;&#12427;&#22580;&#21512;&#12395;&#12527;&#12540;&#12489;&#12503;&#12525;&#12483;&#12488;&#12434;&#20316;&#25104;
    if(is.null(PlotWordCloud()) == FALSE){
      #&#12527;&#12540;&#12489;&#12503;&#12525;&#12483;&#12488;
      #&#38306;&#25968;&#12394;&#12398;&#12391;()&#12434;&#35352;&#36848;
      wordcloud(PlotWordCloud()[, 1], PlotWordCloud()[, 2], scale = c(8, .1),
                random.order = FALSE, rot.per = .10, colors = brewer.pal(8, "Dark2"))
    }else{}
    
  })
  
  #dataTableOutput&#12395;&#20986;&#21147;&#12377;&#12427;renderDataTable&#12467;&#12510;&#12531;&#12489;
  #&#12527;&#12540;&#12489;&#12503;&#12525;&#12483;&#12488;&#12487;&#12540;&#12479;&#12434;ui.R&#12398;dataTableOutput&#12395;&#20986;&#21147;:output$table&#20966;&#29702;
  output$table <- renderDataTable(
    
    expr = PlotWordCloud(),
    options = list(pageLength = 5)
    
  )
  
  #web&#12502;&#12521;&#12454;&#12470;&#12391;&#23455;&#34892;&#12375;&#12383;&#38555;&#12395;&#30011;&#20687;&#31561;&#12434;&#20445;&#23384;&#12377;&#12427;downloadHandler&#12467;&#12510;&#12531;&#12489;
  #&#12527;&#12540;&#12489;&#12503;&#12525;&#12483;&#12488;&#12434;png&#12391;&#20445;&#23384;:output$image&#20966;&#29702;
  #web&#12502;&#12521;&#12454;&#12470;&#12391;&#23455;&#34892;&#26178;&#12398;&#12415;&#21205;&#20316;
  output$image <- downloadHandler(
    #&#12501;&#12449;&#12452;&#12523;&#21517;&#12434;&#25351;&#23450;
    filename = function(){"WordCloudPlot.png"},
    #&#20966;&#29702;&#20869;&#23481;&#12434;&#35352;&#36848;
    content = function(file) {
      png(file)
      wordcloud(PlotWordCloud()[, 1], PlotWordCloud()[, 2], scale = c(8, .1),
                random.order = FALSE, rot.per = .10, colors = brewer.pal(8, "Dark2"))
      dev.off()
    }
  )
})

実行例

・Chrome バージョン 56.0.2924.87 (64-bit)での実行例です。Shinyで習作1でも検索した「Leptailurus serval」結果。


少しでも、あなたの解析が楽になりますように!!けものフレンズ「第10話 ろっじ」の配信が楽しみです。

タイトルとURLをコピーしました