Advance in webApp writing by R

Chin Lin

Thursday, October 2, 2014

前情提要

– 了解App的基本架構(ui.R和server.R)

– 增加控制區參數

– 從網頁上擷取即時資訊

– 將複雜的程式碼打包成一個函數

– 分享你的App至網路上

– 在App中增加新的欄位來選擇醫院屬性

– 在Local端執行排程工作(迴圈 & Sys.sleep())

– 將App設計成讀取Local端檔案來執行

上節課的成果

– 請複製下列這串程式碼(這是三軍總醫院的):

TSGH = function() {
  URL1 = "http://www1.ndmctsgh.edu.tw/ErOnlineNews/ErOnLineData.aspx"
  txt1 = scan(URL1, what="character", encoding="UTF-8")
  txt1_new = paste(txt1, sep="", collapse=" ")
  
  #The result matrix
  Result=matrix(NA,nrow=1,ncol=5)
  rownames(Result)="三軍總醫院"
  colnames(Result)=c("滿床","看診","推床","住院","加護病床")
  
  #The first value
  code.1_1 = "<span id=\"Label7\"><font color=\"Red\">"
  code.1_2 = "</font></span> </td> </tr> <tr> <td> <span id=\"Label3\"><font color=\"Blue\">"
  start.1 = regexpr(code.1_1, txt1_new)
  end.1 = regexpr(code.1_2, txt1_new)
  position.1_1 = start.1[1] + attr(start.1,"match.length")
  position.1_2 = end.1[1] - 1
  Result[1,1]=substr(txt1_new, position.1_1, position.1_2)
  
  #The second value
  code.2_1 = "<span id=\"Label8\"><font color=\"Red\">"
  code.2_2 = "</font></span> </td> </tr> <tr> <td> <span id=\"Label4\"><font color=\"Blue\">"
  start.2 = regexpr(code.2_1, txt1_new)
  end.2 = regexpr(code.2_2, txt1_new)
  position.2_1 = start.2[1] + attr(start.2,"match.length")
  position.2_2 = end.2[1] - 1
  Result[1,2]=substr(txt1_new, position.2_1, position.2_2)
  
  #The third value
  code.3_1 = "<span id=\"Label9\"><font color=\"Red\">"
  code.3_2 = "</font></span> </td> </tr> <tr> <td> <span id=\"Label5\"><font color=\"Blue\">"
  start.3 = regexpr(code.3_1, txt1_new)
  end.3 = regexpr(code.3_2, txt1_new)
  position.3_1 = start.3[1] + attr(start.3,"match.length")
  position.3_2 = end.3[1] - 1
  Result[1,3]=substr(txt1_new, position.3_1, position.3_2)
  
  #The forth value
  code.4_1 = "<span id=\"Label10\"><font color=\"Red\">"
  code.4_2 = "</font></span> </td> </tr> <tr> <td> <span id=\"Label6\"><font color=\"Blue\">"
  start.4 = regexpr(code.4_1, txt1_new)
  end.4 = regexpr(code.4_2, txt1_new)
  position.4_1 = start.4[1] + attr(start.4,"match.length")
  position.4_2 = end.4[1] - 1
  Result[1,4]=substr(txt1_new, position.4_1, position.4_2)
  
  #The fifth value
  code.5_1 = "<span id=\"Label11\"><font color=\"Red\">"
  code.5_2 = "</font></span> </td> </tr> </table> </div> </form> </body> </html>"
  start.5 = regexpr(code.5_1, txt1_new)
  end.5 = regexpr(code.5_2, txt1_new)
  position.5_1 = start.5[1] + attr(start.5,"match.length")
  position.5_2 = end.5[1] - 1
  Result[1,5]=substr(txt1_new, position.5_1, position.5_2)
  
  #print the output
  return(Result)
}

TSGH()

增加不同語言的選項在我們的函數內

TSGH = function(language="English") {
URL1 = "http://www1.ndmctsgh.edu.tw/ErOnlineNews/ErOnLineData.aspx"
txt1 = scan(URL1, what="character", encoding="UTF-8")
txt1_new = paste(txt1, sep="", collapse=" ")

#The result matrix
Result=matrix(NA,nrow=1,ncol=5)
if (language=="English") {
  rownames(Result)="TSGH"
  colnames(Result)=c("Bed status","Waiting for examination","Waiting for bed","Wiating for hospitalize","Waiting for ICU")
}
if (language=="Chinese") {
  rownames(Result)="三軍總醫院"
  colnames(Result)=c("滿床","看診","推床","住院","加護病床")
}

#The first value
code.1_1 = "<span id=\"Label7\"><font color=\"Red\">"
code.1_2 = "</font></span> </td> </tr> <tr> <td> <span id=\"Label3\"><font color=\"Blue\">"
start.1 = regexpr(code.1_1, txt1_new)
end.1 = regexpr(code.1_2, txt1_new)
position.1_1 = start.1[1] + attr(start.1,"match.length")
position.1_2 = end.1[1] - 1
status=substr(txt1_new, position.1_1, position.1_2)

if (language=="English") {
if (status=="是") {Result[1,1]="full"}
if (status=="否") {Result[1,1]="empty"}
}
if (language=="Chinese") {
if (status=="是") {Result[1,1]="是"}
if (status=="否") {Result[1,1]="否"}
}

#The second value
code.2_1 = "<span id=\"Label8\"><font color=\"Red\">"
code.2_2 = "</font></span> </td> </tr> <tr> <td> <span id=\"Label4\"><font color=\"Blue\">"
start.2 = regexpr(code.2_1, txt1_new)
end.2 = regexpr(code.2_2, txt1_new)
position.2_1 = start.2[1] + attr(start.2,"match.length")
position.2_2 = end.2[1] - 1
Result[1,2]=substr(txt1_new, position.2_1, position.2_2)

#The third value
code.3_1 = "<span id=\"Label9\"><font color=\"Red\">"
code.3_2 = "</font></span> </td> </tr> <tr> <td> <span id=\"Label5\"><font color=\"Blue\">"
start.3 = regexpr(code.3_1, txt1_new)
end.3 = regexpr(code.3_2, txt1_new)
position.3_1 = start.3[1] + attr(start.3,"match.length")
position.3_2 = end.3[1] - 1
Result[1,3]=substr(txt1_new, position.3_1, position.3_2)

#The forth value
code.4_1 = "<span id=\"Label10\"><font color=\"Red\">"
code.4_2 = "</font></span> </td> </tr> <tr> <td> <span id=\"Label6\"><font color=\"Blue\">"
start.4 = regexpr(code.4_1, txt1_new)
end.4 = regexpr(code.4_2, txt1_new)
position.4_1 = start.4[1] + attr(start.4,"match.length")
position.4_2 = end.4[1] - 1
Result[1,4]=substr(txt1_new, position.4_1, position.4_2)

#The fifth value
code.5_1 = "<span id=\"Label11\"><font color=\"Red\">"
code.5_2 = "</font></span> </td> </tr> </table> </div> </form> </body> </html>"
start.5 = regexpr(code.5_1, txt1_new)
end.5 = regexpr(code.5_2, txt1_new)
position.5_1 = start.5[1] + attr(start.5,"match.length")
position.5_2 = end.5[1] - 1
Result[1,5]=substr(txt1_new, position.5_1, position.5_2)

#print the output
return(Result)
}

TSGH()
TSGH(language="English")
TSGH(language="Chinese")

練習1

– 下面這個例子是雙和醫院的程式碼

TMUSH = function(language="English") {
  URL2 = "http://eng.shh.org.tw/ER_WEB/ER_WEB/Default.aspx"
  txt2 = scan(URL2, what="character", encoding="UTF-8")
  txt2_new = paste(txt2, sep="", collapse=" ")
  
  #The result matrix
  Result=matrix(NA,nrow=1,ncol=5)
  if (language=="English") {
    rownames(Result)="TMUSH"
    colnames(Result)=c("Bed status","Waiting for examination","Waiting for bed","Wiating for hospitalize","Waiting for ICU")
  }
  if (language=="Chinese") {
    rownames(Result)="雙和醫院"
    colnames(Result)=c("滿床","看診","推床","住院","加護病床")
  }
    
  #The first value
  code.1_1 = "119滿載</td> <td class=\"style1\"> <span id=\"off\"><b><font color=\"Red\">"
  code.1_2 = "</font></b></span> </td> </tr> <tr> <td class=\"style3\"> 等待看診人數"
  start.1 = regexpr(code.1_1, txt2_new)
  end.1 = regexpr(code.1_2, txt2_new)
  position.1_1 = start.1[1] + attr(start.1,"match.length")
  position.1_2 = end.1[1] - 1
  status=substr(txt2_new, position.1_1, position.1_2)
  
  if (language=="English") {
    if (status=="未滿載") {Result[1,1]="empty"}
    if (status=="滿載") {Result[1,1]="full"}
  }
  if (language=="Chinese") {
    if (status=="未滿載") {Result[1,1]="否"}
    if (status=="滿載") {Result[1,1]="是"}
  }
  
  #The second value
  code.2_1 = "等待看診人數 </td> <td class=\"style1\"> <span id=\"Label1\">"
  code.2_2 = "</span> </td> </tr> <tr> <td class=\"style4\"> 等待推床人數"
  start.2 = regexpr(code.2_1, txt2_new)
  end.2 = regexpr(code.2_2, txt2_new)
  position.2_1 = start.2[1] + attr(start.2,"match.length")
  position.2_2 = end.2[1] - 1
  Result[1,2]=substr(txt2_new, position.2_1, position.2_2)
  
  #The third value
  code.3_1 = "等待推床人數</td> <td> <span id=\"Label2\">"
  code.3_2 = "</span> </td> </tr> <tr> <td class=\"style4\"> 等待住院人數"
  start.3 = regexpr(code.3_1, txt2_new)
  end.3 = regexpr(code.3_2, txt2_new)
  position.3_1 = start.3[1] + attr(start.3,"match.length")
  position.3_2 = end.3[1] - 1
  Result[1,3]=substr(txt2_new, position.3_1, position.3_2)
  
  #The forth value
  code.4_1 = "等待住院人數</td> <td> <span id=\"Label3\">"
  code.4_2 = "</span> </td> </tr> <tr> <td class=\"style4\"> 等待加護人數"
  start.4 = regexpr(code.4_1, txt2_new)
  end.4 = regexpr(code.4_2, txt2_new)
  position.4_1 = start.4[1] + attr(start.4,"match.length")
  position.4_2 = end.4[1] - 1
  Result[1,4]=substr(txt2_new, position.4_1, position.4_2)
  
  #The fifth value
  code.5_1 = "等待加護人數</td> <td> <span id=\"Label4\">"
  code.5_2 = "</span> </td> </tr> </table> <br /> 最後更新"
  start.5 = regexpr(code.5_1, txt2_new)
  end.5 = regexpr(code.5_2, txt2_new)
  position.5_1 = start.5[1] + attr(start.5,"match.length")
  position.5_2 = end.5[1] - 1
  Result[1,5]=substr(txt2_new, position.5_1, position.5_2)
  
  #print the output
  return(Result)
}

TMUSH()
TMUSH(language="English")
TMUSH(language="Chinese")

合併檔案並增加欄位

Result1=TSGH()
Result2=TMUSH()

Final=rbind(Result1,Result2)
Final
Area=c("Taipei","New Taipei")
Final=data.frame(Final)
Final[Area=="Taipei",]
Final[Area=="New Taipei",]

在App中增加新的欄位來選擇醫院屬性

– global.R

TMUSH = function(language="English") {
  URL2 = "http://eng.shh.org.tw/ER_WEB/ER_WEB/Default.aspx"
  txt2 = scan(URL2, what="character", encoding="UTF-8")
  txt2_new = paste(txt2, sep="", collapse=" ")
  
  #The result matrix
  Result=matrix(NA,nrow=1,ncol=5)
  if (language=="English") {
    rownames(Result)="TMUSH"
    colnames(Result)=c("Bed status","Waiting for examination","Waiting for bed","Wiating for hospitalize","Waiting for ICU")
  }
  if (language=="Chinese") {
    rownames(Result)="雙和醫院"
    colnames(Result)=c("滿床","看診","推床","住院","加護病床")
  }
  
  #The first value
  code.1_1 = "119滿載</td> <td class=\"style1\"> <span id=\"off\"><b><font color=\"Red\">"
  code.1_2 = "</font></b></span> </td> </tr> <tr> <td class=\"style3\"> 等待看診人數"
  start.1 = regexpr(code.1_1, txt2_new)
  end.1 = regexpr(code.1_2, txt2_new)
  position.1_1 = start.1[1] + attr(start.1,"match.length")
  position.1_2 = end.1[1] - 1
  status=substr(txt2_new, position.1_1, position.1_2)
  
  if (language=="English") {
    if (status=="未滿載") {Result[1,1]="empty"}
    if (status=="滿載") {Result[1,1]="full"}
  }
  if (language=="Chinese") {
    if (status=="未滿載") {Result[1,1]="否"}
    if (status=="滿載") {Result[1,1]="是"}
  }
  
  #The second value
  code.2_1 = "等待看診人數 </td> <td class=\"style1\"> <span id=\"Label1\">"
  code.2_2 = "</span> </td> </tr> <tr> <td class=\"style4\"> 等待推床人數"
  start.2 = regexpr(code.2_1, txt2_new)
  end.2 = regexpr(code.2_2, txt2_new)
  position.2_1 = start.2[1] + attr(start.2,"match.length")
  position.2_2 = end.2[1] - 1
  Result[1,2]=substr(txt2_new, position.2_1, position.2_2)
  
  #The third value
  code.3_1 = "等待推床人數</td> <td> <span id=\"Label2\">"
  code.3_2 = "</span> </td> </tr> <tr> <td class=\"style4\"> 等待住院人數"
  start.3 = regexpr(code.3_1, txt2_new)
  end.3 = regexpr(code.3_2, txt2_new)
  position.3_1 = start.3[1] + attr(start.3,"match.length")
  position.3_2 = end.3[1] - 1
  Result[1,3]=substr(txt2_new, position.3_1, position.3_2)
  
  #The forth value
  code.4_1 = "等待住院人數</td> <td> <span id=\"Label3\">"
  code.4_2 = "</span> </td> </tr> <tr> <td class=\"style4\"> 等待加護人數"
  start.4 = regexpr(code.4_1, txt2_new)
  end.4 = regexpr(code.4_2, txt2_new)
  position.4_1 = start.4[1] + attr(start.4,"match.length")
  position.4_2 = end.4[1] - 1
  Result[1,4]=substr(txt2_new, position.4_1, position.4_2)
  
  #The fifth value
  code.5_1 = "等待加護人數</td> <td> <span id=\"Label4\">"
  code.5_2 = "</span> </td> </tr> </table> <br /> 最後更新"
  start.5 = regexpr(code.5_1, txt2_new)
  end.5 = regexpr(code.5_2, txt2_new)
  position.5_1 = start.5[1] + attr(start.5,"match.length")
  position.5_2 = end.5[1] - 1
  Result[1,5]=substr(txt2_new, position.5_1, position.5_2)
  
  #print the output
  return(Result)
}

TSGH = function(language="English") {
  URL1 = "http://www1.ndmctsgh.edu.tw/ErOnlineNews/ErOnLineData.aspx"
  txt1 = scan(URL1, what="character", encoding="UTF-8")
  txt1_new = paste(txt1, sep="", collapse=" ")
  
  #The result matrix
  Result=matrix(NA,nrow=1,ncol=5)
  if (language=="English") {
    rownames(Result)="TSGH"
    colnames(Result)=c("Bed status","Waiting for examination","Waiting for bed","Wiating for hospitalize","Waiting for ICU")
  }
  if (language=="Chinese") {
    rownames(Result)="三軍總醫院"
    colnames(Result)=c("滿床","看診","推床","住院","加護病床")
  }
  
  #The first value
  code.1_1 = "<span id=\"Label7\"><font color=\"Red\">"
  code.1_2 = "</font></span> </td> </tr> <tr> <td> <span id=\"Label3\"><font color=\"Blue\">"
  start.1 = regexpr(code.1_1, txt1_new)
  end.1 = regexpr(code.1_2, txt1_new)
  position.1_1 = start.1[1] + attr(start.1,"match.length")
  position.1_2 = end.1[1] - 1
  status=substr(txt1_new, position.1_1, position.1_2)
  
  if (language=="English") {
    if (status=="是") {Result[1,1]="full"}
    if (status=="否") {Result[1,1]="empty"}
  }
  if (language=="Chinese") {
    if (status=="是") {Result[1,1]="是"}
    if (status=="否") {Result[1,1]="否"}
  }
  
  #The second value
  code.2_1 = "<span id=\"Label8\"><font color=\"Red\">"
  code.2_2 = "</font></span> </td> </tr> <tr> <td> <span id=\"Label4\"><font color=\"Blue\">"
  start.2 = regexpr(code.2_1, txt1_new)
  end.2 = regexpr(code.2_2, txt1_new)
  position.2_1 = start.2[1] + attr(start.2,"match.length")
  position.2_2 = end.2[1] - 1
  Result[1,2]=substr(txt1_new, position.2_1, position.2_2)
  
  #The third value
  code.3_1 = "<span id=\"Label9\"><font color=\"Red\">"
  code.3_2 = "</font></span> </td> </tr> <tr> <td> <span id=\"Label5\"><font color=\"Blue\">"
  start.3 = regexpr(code.3_1, txt1_new)
  end.3 = regexpr(code.3_2, txt1_new)
  position.3_1 = start.3[1] + attr(start.3,"match.length")
  position.3_2 = end.3[1] - 1
  Result[1,3]=substr(txt1_new, position.3_1, position.3_2)
  
  #The forth value
  code.4_1 = "<span id=\"Label10\"><font color=\"Red\">"
  code.4_2 = "</font></span> </td> </tr> <tr> <td> <span id=\"Label6\"><font color=\"Blue\">"
  start.4 = regexpr(code.4_1, txt1_new)
  end.4 = regexpr(code.4_2, txt1_new)
  position.4_1 = start.4[1] + attr(start.4,"match.length")
  position.4_2 = end.4[1] - 1
  Result[1,4]=substr(txt1_new, position.4_1, position.4_2)
  
  #The fifth value
  code.5_1 = "<span id=\"Label11\"><font color=\"Red\">"
  code.5_2 = "</font></span> </td> </tr> </table> </div> </form> </body> </html>"
  start.5 = regexpr(code.5_1, txt1_new)
  end.5 = regexpr(code.5_2, txt1_new)
  position.5_1 = start.5[1] + attr(start.5,"match.length")
  position.5_2 = end.5[1] - 1
  Result[1,5]=substr(txt1_new, position.5_1, position.5_2)
  
  #print the output
  return(Result)
}

在App中增加新的欄位來選擇醫院屬性-續

– ui.R

library(shiny)

# Define UI for ER imformation 
shinyUI(pageWithSidebar(
  
  # Application title
  headerPanel("ER imformation"),
  
  # Selected the hospitals
  sidebarPanel(
    radioButtons("language", h3("Selected the language"), c("English" = "English","中文" = "Chinese")),
    conditionalPanel(condition="input.language=='English'",
      radioButtons("focus1", h3("Do you want to focus a city?"), c("Yes" = "yes", "No" = "no")),
      conditionalPanel(condition="input.focus1=='yes'",                    
        radioButtons("city1", h3("Selected the focused city"), c("Taipei" = "Taipei", "New Taipei" = "New Taipei"))
      )
    ),
    conditionalPanel(condition="input.language=='Chinese'",
      radioButtons("focus2", h3("你只想看一個城市嗎?"), c("是" = "yes", "否" = "no")),
      conditionalPanel(condition="input.focus2=='yes'",                    
        radioButtons("city2", h3("請選擇你想看的城市"), c("台北市" = "Taipei", "新北市" = "New Taipei"))
      )
    )    
  ),
  
  # Show a table including user selection
  mainPanel(
    tableOutput("Final")
  )
))

– server.R

library(shiny)

# Define server logic required to generate and plot a random distribution
shinyServer(function(input, output) {
  
  output$Final =  renderTable({      
    Result=rbind(TSGH(language=input$language),TMUSH(language=input$language))
    Result=data.frame(Result)
    Area=c("Taipei","New Taipei")
    if (input$language=="English"&input$focus1=="yes") {
      return(Result[Area==input$city1,])
    }
    if (input$language=="Chinese"&input$focus2=="yes") {
      return(Result[Area==input$city2,])      
    }
    if (input$language=="English"&input$focus1=="no") {return(Result)}
    if (input$language=="Chinese"&input$focus2=="no") {return(Result)}
  })
  
})

練習2

– 可以的話,先上傳目前的成果到網路上!

在Local端執行排程工作

– 那就是當醫院一多起來,App的運算速度就變慢許多

– 因此,我們要學會兩個功能(迴圈 & Sys.sleep())

基本函數介紹

Result1=TSGH()
Result2=TMUSH()

Final=rbind(Result1,Result2)
Final

– 請試著將1改成其他數字

filenames=paste("d:/Final",1,".csv",sep="")
write.csv(Final,"d:/Final.csv")
Sys.sleep(5) # 讓系統休息5秒

– 我們結合上述幾個程式碼讓他每隔3秒就存一個新檔案,連續儲存5次

for (i in 1:5) {
Sys.sleep(3)
filenames=paste("d:/Final",i,".csv",sep="")
write.csv(Final,filenames)
}

練習3

  1. 剛剛的指令只是讓他“每隔一段時間就寫出一次檔案”,能否改成“每隔一段時間就掃描一次,並且寫出檔案”

  2. 考慮到未來我們要使用App來讀檔,我們必須寫出2個檔案,1個是歷史紀錄,另1個是每次使用者訪問時都必須讀的檔案?

  3. 可否同時有中文&英文的輸出?

將App設計成讀取Local端檔案來執行

– ui.R(不變)

library(shiny)

# Define UI for ER imformation 
shinyUI(pageWithSidebar(
  
  # Application title
  headerPanel("ER imformation"),
  
  # Selected the hospitals
  sidebarPanel(
    radioButtons("language", h3("Selected the language"), c("English" = "English","中文" = "Chinese")),
    conditionalPanel(condition="input.language=='English'",
      radioButtons("focus1", h3("Do you want to focus a city?"), c("Yes" = "yes", "No" = "no")),
      conditionalPanel(condition="input.focus1=='yes'",                    
        radioButtons("city1", h3("Selected the focused city"), c("Taipei" = "Taipei", "New Taipei" = "New Taipei"))
      )
    ),
    conditionalPanel(condition="input.language=='Chinese'",
      radioButtons("focus2", h3("你只想看一個城市嗎?"), c("是" = "yes", "否" = "no")),
      conditionalPanel(condition="input.focus2=='yes'",                    
        radioButtons("city2", h3("請選擇你想看的城市"), c("台北市" = "Taipei", "新北市" = "New Taipei"))
      )
    )    
  ),
  
  # Show a table including user selection
  mainPanel(
    tableOutput("Final")
  )
))

– server.R

library(shiny)

# Define server logic required to generate and plot a random distribution
shinyServer(function(input, output) {
  
  output$Final =  renderTable({      
    Result1=read.csv("d:/Final_English.csv",row.names=1)
    Result2=read.csv("d:/Final_Chinese.csv",row.names=1)
    Area=c("Taipei","New Taipei")
    if (input$language=="English"&input$focus1=="yes") {
      return(Result1[Area==input$city1,])
    }
    if (input$language=="Chinese"&input$focus2=="yes") {
      return(Result2[Area==input$city2,])      
    }
    if (input$language=="English"&input$focus1=="no") {return(Result1)}
    if (input$language=="Chinese"&input$focus2=="no") {return(Result2)}
  })
  
})

練習4

  1. 找某一台台電腦負責定時掃瞄網頁,並且儲存檔案至upload資料夾內

  2. 找另一台電腦寫出App,令他隨時讀取upload資料夾內的資訊

持續學習