2020年9月26日 星期六

29_R互動式網頁_加入KPI指標

 承上一篇的主題及程式碼,本篇規劃在右側上方加入KPI營運指標,但又發覺直方圖及拉桿似乎太佔位置了,所以在加入KPI營運指標前,將直方圖及拉感合成一頁並分為兩個頁籤,程式依然以ui.R程式為主

library(shiny)
library(shinydashboard)
shinyUI(
  dashboardPage(
    dashboardHeader(title = "This is header"),
    dashboardSidebar(
      
      sidebarMenu(
        sidebarSearchForm("searchText","buttonsearch","search"),#加入搜尋
      menuItem("儀表板",tabName = "dashboard",icon = icon("dashboard")),
        menuSubItem("財務儀表板",tabName = "finance"),
        menuSubItem("銷售儀表板",tabName = "sales"),
      menuItem("資料分析"),
      menuItem("原始資料")
    )),
    dashboardBody(
      tabItems(
        tabItem(tabName = "dashboard",
                fluidRow(
                  tabBox(
                  tabPanel(title = "財務直方圖",status = "primary",solidHeader = T,plotOutput("histogram")),#move here
                  tabPanel(title = "儀表板控制",status = "warning",solidHeader = T,
                      sliderInput("bins","Number of Breaks",1,100,50),
                      textInput("text_input","search opptunities",value = "123456"))#move here
                  )
                )),
                tabItem(tabName = "finance",
                        h1("財務儀表板")
                        ),
                tabItem(tabName = "sales",
                        h2("銷售儀表板"))
                )
      )
    )
  )

其實我們可以看到程式碼,我們改的地方主要為dishboardBody中fluidRow的程式加入tabBox()將直方圖及拉桿包起來,並將直方圖原先box改為tabPanel,同樣拉桿的程式碼前方加入tabPanel,此時可為一頁又分別為兩個頁籤,這樣的好處是若我在後續規劃有其他的統計圖,可在增加一個tabBox方便我的規畫所增加的內容,成果圖如下



現在dashBoard上方加入三個營運KPI分別為銷售金額、倉庫周轉率、核准訂單,所以會加入fliudRow()內含有兩個infoBox及一個infoBoxOutput進行呈現,程式碼如下

ui.R程式如下
library(shiny)
library(shinydashboard)

shinyUI(
  dashboardPage(
    dashboardHeader(title = "This is header"),
    dashboardSidebar(
      
      sidebarMenu(
        sidebarSearchForm("searchText","buttonsearch","search"),#加入搜尋
      menuItem("儀表板",tabName = "dashboard",icon = icon("dashboard")),
        menuSubItem("財務儀表板",tabName = "finance"),
        menuSubItem("銷售儀表板",tabName = "sales"),
      menuItem("資料分析"),
      menuItem("原始資料")
    )),
    dashboardBody(
      tabItems(
        tabItem(tabName = "dashboard",
                fluidRow(
                  infoBox("銷售總額美元",1000,icon = icon("thumbs-up")),
                  infoBox("倉庫周轉率%",paste0('20'),icon = icon("warning")),
                  infoBoxOutput("approved")
                ),
                fluidRow(
                  tabBox(
                  tabPanel(title = "財務直方圖",status = "primary",solidHeader = T,plotOutput("histogram")),#move here
                  tabPanel(title = "儀表板控制",status = "warning",solidHeader = T,
                      sliderInput("bins","Number of Breaks",1,100,50),
                      textInput("text_input","search opptunities",value = "123456"))#move here
                  ),
                  tabBox()
                )),
                tabItem(tabName = "finance",
                        h1("財務儀表板")
                        ),
                tabItem(tabName = "sales",
                        h2("銷售儀表板"))
                )
      )

    )
  )

server.R程式如下
library(shiny)
library(shinydashboard)

shinyServer(function(input,output){
  output$histogram <- renderPlot({
    hist(faithful$eruptions,breaks = input$bins)
  })
  output$approved <- renderInfoBox({
    infoBox("已批准訂單","10,000,000",icon = icon("bar-chart-o"))
  })
})

上述程式碼中我們可以發現在ui.R中的infoBoxOutput,相對在server.R中也相對應,成果圖如下








28_R互動式網頁_版型調整

 承上一篇主題及程式碼我們已經完成初步的儀表板版型,本篇會進入版型的調整,對於我而言我會將UI的版型完成框架後,進行版型不足之處的加強,當然這是我的習慣,每個人都有自己開發的流程,所以本篇會以下列主題進行UI版型的調整

一、SidebarMenu內容調整

SidebarMenu會進行三個部分做調整包含滑桿下移、增加條件搜尋、增加文字框輸入等三個部分,程式碼如下,如同我針對ui.R做調整

library(shiny)
library(shinydashboard)
shinyUI(
  dashboardPage(
    dashboardHeader(title = "This is header"),
    dashboardSidebar(
      
      sidebarMenu(
        sidebarSearchForm("searchText","buttonsearch","search"),#加入搜尋
      menuItem("儀表板",tabName = "dashboard",icon = icon("dashboard")),
        menuSubItem("財務儀表板",tabName = "finance"),
        menuSubItem("銷售儀表板",tabName = "sales"),
      menuItem("資料分析"),
      menuItem("原始資料"),
      sliderInput("bins","Number of Breaks",1,100,50),#將滑桿移至功能列下方
      textInput("text_input","search opportunities",value = "123456")#增加文字輸入框
    )),
    dashboardBody(
      tabItems(
        tabItem(tabName = "dashboard",
                fluidRow(
                  box(plotOutput("histogram"))
                )),
                tabItem(tabName = "finance",
                        h1("財務儀表板")
                        ),
                tabItem(tabName = "sales",
                        h2("銷售儀表板"))
                )
      )
    )
  )

在ui.R程式碼中可看到加入註記#字號,為本次調整的部分,其實都不示很難,都是一般程式與法範圍功能即可完成,成果圖如下圖,當然條件搜尋即文字輸入沒有反應,因為沒跟資料做連結。


二、直方圖的調整

圖中我們可以感受直方圖很陽春!所以我們會將直方圖加點顏色,以及調整直方圖的動態滑桿拉至與直方圖相同的Body中並加入顏色,讓側邊功能選單能更單純以功能為主,在調整還是以ui.R為主程式碼如下

library(shiny)
library(shinydashboard)
shinyUI(
  dashboardPage(
    dashboardHeader(title = "This is header"),
    dashboardSidebar(
      
      sidebarMenu(
        sidebarSearchForm("searchText","buttonsearch","search"),#加入搜尋
      menuItem("儀表板",tabName = "dashboard",icon = icon("dashboard")),
        menuSubItem("財務儀表板",tabName = "finance"),
        menuSubItem("銷售儀表板",tabName = "sales"),
      menuItem("資料分析"),
      menuItem("原始資料")
    )),
    dashboardBody(
      tabItems(
        tabItem(tabName = "dashboard",
                fluidRow(
                  box(title = "財務直方圖",status = "primary",solidHeader = T,plotOutput("histogram")),#move here
                  box(title = "儀表板控制",status = "warning",solidHeader = T,
                      sliderInput("bins","Number of Breaks",1,100,50),
                      textInput("text_input","search opptunities",value = "123456"))#move here
                )),
                tabItem(tabName = "finance",
                        h1("財務儀表板")
                        ),
                tabItem(tabName = "sales",
                        h2("銷售儀表板"))
                )
      )
    )
  )

我們可以看程式碼其實並沒有多撰寫甚麼程式,只是移動功能的位置,其實在做UI的規劃會花很多的時間調整各功能的位置,有時會看到成果時才發現,UI還可以在做調整。



下一篇!會加入KPI指標





2020年9月25日 星期五

27_R互動式網頁_Dashboard之版型建立

 在前面幾篇都在介紹Shiny套件一些基礎的概念,當然Shiny套件不僅是如此,也不可能幾篇就能介紹完畢,但前面幾篇為重要的操作語言的概念,可了解很多大神的作品及自學的基礎,就像前面幾篇所提到當面對一些新的語法不外乎就是重基礎學起,但又不知如何是好又囫圇吞棗,學習的過程總充滿了挫折,喪失了寫程式的樂趣。

而今天這篇Dashbord儀表板會著重在ui.R中,因為當分析的結果總是要出去跟其他人溝通,在商業的世界可能是老闆或是單位的主管及決策者,而這些人可能不懂資訊就是一般的使用者,若我們以工程是師的概念將結果呈現,效果可能不太好,所以在Shiny套件有Dashboard能讓我們快速製作專業的網頁,當然該套件整合了css語法,但又不像css語法那麼羅唆,所以後續的幾篇程式碼是延續的。

本次儀表板的主題為公司營運管理儀表板,而資料採用R黃石公園溫泉爆發時間與等待時間資料集,對!我知道資料集的內容跟主題不一樣,但我們主要了解Dashboard套件的撰寫方式,須以資料作呈現,若以真實的世界資料為主工程就大了!反而混淆本次的主題,未來可置換資料集即可。

當然開一個資料夾分別存放ui.R及server.R兩個檔案,程式如下

ui.R程式如下

library(shiny)
library(shinydashboard)
shinyUI(
  dashboardPage(
    dashboardHeader(title = "This is header"),
    dashboardSidebar(
      sliderInput("bins","Number of Breaks",1,100,50),
      menuItem("儀表板"),
        menuSubItem("財務儀表板"),
        menuSubItem("銷售儀表板"),
      menuItem("資料分析"),
      menuItem("原始資料")
    ),
    dashboardBody(
      fluidRow(
        box(plotOutput("histogram"))
        
      )
    )
  )
)

server.R程式如下

library(shiny)
library(shinydashboard)
shinyServer(function(input,output){
  output$histogram <- renderPlot({
    hist(faithful$eruptions,breaks = input$bins)
  })
})

ui.R程式中其實細細看來很像html語法,但又沒有html語法的囉唆!簡潔有力,但其中要了解的是sliderInput("bins","Number of Breaks",1,100,50),這為動態拉桿的語法,而在dashboardBody中宣告要繪製直方圖,配合拉桿進行拖曳。

server.R程式中語法很簡單!配合上述所說本次以ui為主,所以我們要了解 hist(faithful$eruptions,breaks = input$bins)該句語法即可,所以翻成白話文為繪製直方圖,使用黃石公園資料集中的爆發時間欄位,並配合動態拉桿中的變數為bins。

成果如下圖



在成果圖上操作發現所功能都沒有連結,也就是html功能都連到一個超連結,所以下面就將功能連上連結,ui.R程式如下

library(shiny)
library(shinydashboard)

shinyUI(
  dashboardPage(
    dashboardHeader(title = "This is header"),
    dashboardSidebar(
      sliderInput("bins","Number of Breaks",1,100,50),
      sidebarMenu(
      menuItem("儀表板",tabName = "dashboard",icon = icon("dashboard")),
        menuSubItem("財務儀表板",tabName = "finance"),
        menuSubItem("銷售儀表板",tabName = "sales"),
      menuItem("資料分析"),
      menuItem("原始資料")
    )),
    dashboardBody(
      tabItems(
        tabItem(tabName = "dashboard",
                fluidRow(
                  box(plotOutput("histogram"))
                )),
                tabItem(tabName = "finance",
                        h1("財務儀表板")
                        ),
                tabItem(tabName = "sales",
                        h2("銷售儀表板"))
                )
      )

    )
  )

程式碼中我們可以發現其實跟html語法的邏輯是相同的,在menuItem指定功能名稱,在dashboardBody指定對應的功能名稱,而在dashboardBody中的tabItem撰寫該功能的程式;而在上述的程式碼中tabItems和tabItem兩個我搞了一小時,看來看去都沒問題程式就跑不起來,原來可以看到兩個函式一個有s一個沒s,有s的為相同類型的東西有很多加s,這是英文的基本文法,搞完才發現原來就這麼簡單,下面為成果圖



在成果圖上可以看儀表板有圖示icon,在程式碼中也有看到,其實Shiny套件也支援一般網頁第三方圖示套件,我們在console中輸入?icon即可出現相關說明如下圖


我們可看到網址有在寫前端的朋友應該都不陌生,只要知道該圖示的名稱,如本篇程式輸入圖示名稱,及自動去該網站取得該圖示。

今天到這邊,明天見!













2020年9月24日 星期四

26_互動式網頁_關聯規則

 關聯關則是資料探勘中很有名的買尿布有一定的機率會買啤酒,所以尿布和啤酒有一定的關聯度,所以在消費行為分析上是很有用,而分析的結果店家可以進行商品組合促銷,增加商品銷售率,關聯規則本來是要在店商分析中說明,不過沒關係配合Shiny網頁讓行銷人員透過Web進行分析,不過這些預測性的東西都須要對一些名詞的理解才能解釋,所以在這邊以尿布和啤酒,言簡意賅做解釋。

Support (支持度) : 意思是某特定種類在所有種類的比重,例如我有100名會員,其中有20名購買過尿布,則support(尿布) = 20% 。

Confidence (信賴度) : 意思是某A種類中,含有某B種類的比重,例如我有100名會員,其中40人買過啤酒,而這40買過啤酒者當中,又另有10人買過尿布,則confidence(啤酒->尿布) = 10/40 = 25% 。

Lift (提升度) : 意思為某兩者關係的比值,如果小於1 代表兩者是負相關,等於1 表示兩者獨立,大於1 表示兩者正相關,公式為confidence(A->B) / support(B) ,帶入上述例子可表示成 lift(尿布->啤酒) = 25/20 = 1.25 。

在R執行關聯規則須將原本資料結構dataframe轉換成transactions類別,也就是二元關聯矩陣,聽起來很像很偉大,其實就一個指令而已,而本次資料集採用套件arules中的Groceries內建資料集,該資料集為便利商店30天內的交易共計9835 筆,169各類別商品,該資料集已經為transactions資料類別,程式如下:

server.R程式

library(shiny)
library(arules)
shinyServer(function(input,output){
  
  output$mba <- renderPrint({
    rules <- apriori(Groceries,parameter = list(support=.001,
                                                confidence=.8))
    inspect(rules)
  })
  
})
ui.R程式
library(shiny)

shinyUI(fluidPage(
  sidebarLayout(
    sidebarPanel(
    
    ),
    mainPanel(
      verbatimTextOutput("mba")
    )
  )
))

在server程式中將商品的關聯結果採用renderPrint(),而不採用renderTable因為試過所呈現的效果不好,而在ui.R使用verbatimTextOutput(),該函式是建立文字元素通常是跟renderPrint()配合使用,因此成果如下圖


上圖我們可以看到關聯規則將所有的結果呈現,若使用者要調整不同的支持度和信賴度是無法調整,因為我們在server.R將兩個值給了固定值,所以我們將調整可以讓使用者調整兩個值,程式如下

ui.R程式調整如下

library(shiny)
shinyUI(fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput("sup","請選擇支持度",choices = c(.1,.01,.05,.001,.005)),
      selectInput("conf","請選擇信賴度",choices = c(.5,.6,.7,.8,.9))
    ),
    mainPanel(
      verbatimTextOutput("mba")
    )
  )
))

server.R程式調整如下

library(shiny)
library(arules)
shinyServer(function(input,output){
  
  output$mba <- renderPrint({
    rules <- apriori(Groceries,parameter = list(support=as.numeric(input$sup),
                                                confidence=as.numeric(input$conf)))
    inspect(rules)
  })
})

在上述程式在ui.R中設定兩個變數分別為sup及conf`,存放支持度和信賴度的值,因此在server.R將值帶入,成果如下圖


以第一筆紅框來講,買{酸奶,優格}=>{全指牛奶}來看,兩者商品同時出現占所有商品的1%,而買了{酸奶,優格}會買{全指牛奶}佔全部數據58%,兩者商品的提升2.2為正相關。


2020年9月23日 星期三

25_R互動式網頁_DataTable

 在前面有介紹到Shiny套件在網頁呈現資料表格的方式,當然是很陽春!而今天我們在開發Web時都會常做的頁面,將資料呈現在網頁上,可讓使用者選擇整個頁面總共出現幾筆資料,並有關鍵字可進行搜尋,網頁的下方有資料的分頁。

我相信!在開發Web頁面時這些都是很基本的功能,甚至有時使用者會要求依據他篩選的資料要求,下載成csv或Execl檔案,供它們後續的加值應用。

因此本篇將以R的資料集iris進行,首先也是開一個新的資料夾,並將ui.R及server.R開新檔分別命名,當然也可以將之前幾篇的檔案複製過來;接下來安裝套件DT,而DT套件是甚麼?DT套件使得JavaScript中的方法能在R中被應用,並將矩陣或者數據表在網頁中可視化成表格,程式碼如下

ui.R程式

library(shiny)
library(DT)
ui <- fluidPage(
  titlePanel("Data Table Download"),
  sidebarLayout(
    sidebarPanel(
      
    ),
    mainPanel(
      DT::dataTableOutput("iris")
    )
  )
)

server.R程式

library(shiny)
server <- shinyServer(function(input,output){
  output$iris <- DT::renderDataTable({
    iris
  })
})

成果如下


老實說真的很簡單!做出來東西雖然不很炫!但簡單乾淨,當然有很多參數可調,可使用?DT()就會有眾多參數進行調整,接下來就是依據使用者的篩選後的結果下載,目前我們的搜尋針對項次做搜尋,而搜尋的結果可下載成csv檔案,本次只要修改server.R即可,ui.R維持原樣程式碼如下
library(shiny)
server <- shinyServer(function(input,output){
  output$iris <-  DT::renderDataTable({
    DT::datatable(iris,
                  extensions = 'Buttons',
                  options = list(
                    dom = 'Blfrtip',
                    buttons = 
                      list(
                        list(
                          extend = 'csv',
                          buttons = c('csv'),
                          exportOptions = list(
                            modifiers = list(page = "current")
                          )
                        ))
                  )
    )
  })
  
})

其中程式碼中Blfrtip是有意義不是單純字串,解釋如下

l- l更改輸入量
f- f過濾輸入
t-有t能力!
i-表i信息摘要
p- p攪拌控制
r- r處理顯示元素

成果如下



下一篇見!









2020年9月21日 星期一

24_R互動式網頁_Shiny Plot

 上一篇中將資料集以renderTable()涵式以往頁方式呈現,並以動態的方式進行選擇,讓使用者能夠清楚瞭該資料集的結構,而今天我們將了解繪圖的部分,一樣我們還是使用鐵達尼的資料集,並以上一篇的程式碼為基礎進行程式碼的撰寫

首先我們在ui.R撰寫,程式如下

library(shiny)
ui <- fluidPage(
  titlePanel("This is a demo"),
  sidebarLayout(
    sidebarPanel(
      selectInput("inState","請依鐵達尼資料集選擇欄位",choices = names(titanic))
    ),
    mainPanel(
      plotOutput("titanicData")
    )
  )
)

上圖程式碼跟上一篇差不多,不一樣,choices = names(titanic),告訴Shiny套件鐵達尼資料集內所有的變數都可進行選擇;在上一篇我們要呈現資料集的表格,而本次要呈現圖形所以採用  plotOutput("titanicData")涵式告知套件,接下進入到server.R檔案撰寫,程式如下

library(shiny)
server <- shinyServer(function(input,output){
  output$titanicData <- renderPlot({
    hist(titanic[,input$inState])
   
 #stateFilter <- subset(titanic,titanic$Pclass == input$inState)
  })
})

我們把上一篇的語法變為註解,我們可以發現兩者不同之處,告訴套件我們要繪圖renderPlot(),而圖怎麼多我們要要會甚麼圖ㄋ?所以告訴套件繪製直方圖hist(),那直方圖的資料你需要以哪個值為主input$inState,而這個就是在ui.R檔案所設的變數名稱,而我們可以注意input$inState在逗號的右邊,意思為選擇欄相對在逗號的左邊為選擇行,而詳細的部分可參考本篇的第一篇。

最後的成果如下圖



若你的欄位是字串會出現錯誤畫面,不過這不影響我們金要講的重點!

下一篇見!





2020年9月20日 星期日

23_R互動式網頁_Shiny table

 上一篇提到在Shiny套件中具備ui和server兩個物件,ui就是網頁的版型及事件,server將前端的ui進行運算,所以這兩個物件是Shiny套件很重要的觀念,我們延續上一篇的內容發現ui及server都是寫在同一個檔案app.R中,在簡單的程式中這樣是沒有問題,但是在複雜的需求中這樣的寫法就不妥了,所以Shiny套件中的說明建議開發者將ui及server分為兩個檔案撰寫,在維護中也會比較簡單,在修改程式碼中滾輪也不會滾到變成多爾袞。

在分成成各個檔案撰寫聽起來好像有點困難,其實不難其實跟.NET一樣一個專案一個資料夾,資料夾內有網頁所需的檔案以及ui.R及server.R,而分成兩個檔案只需將前一篇的ui貼製ui.R即可,server也是如此,如下圖


成果如下:



要執行時在ui或server兩個檔案都可執行,按下Run App即可


接下來我們要做一個web系統經常做的事,就是依下拉選單的選擇後出現屬於下拉所選的資料,如此的好處因為使用者不會想看所有的資料,所以依下拉選單篩選所屬資料從以前到現在歷久不衰,所以我們使用鐵達尼的資料,先開一個新檔把資料讀進R中,而資料集和讀進R中可參閱第二篇有資料集的下載網址及第三篇將資料至R的程式中。

ui.R程式如下

library(shiny)

ui <- fluidPage(
  titlePanel("This is a demo"),
  sidebarLayout(
    sidebarPanel(
      selectInput("inState","請選擇船艙等級",choices = titanic$Pclass)
    ),
    mainPanel(
      tableOutput("titanicData")
    )
  )
)

server.R程式如下
library(shiny)
server <- shinyServer(function(input,output){
  output$titanicData <- renderTable({
    stateFilter <- subset(titanic,titanic$Pclass == input$inState)
  })
})

在程式碼中跟上一篇shiny的程式都相同,只有renderTable()涵式及subset()涵式不一樣,因本次是要依下拉選單篩選出來的資料,所以是以table方式出現,所以使用renderTable()進行計算;篩選出來的資料使用subset()資料子集涵式包裹。

其實相對的參數都不難理解,成果如下圖

當然你也使用其他資料集自行實驗一下,其實我寫這段時蠻訝異的!因為真的很簡單,比以前在開發web同樣的功能,設過來設過去,有時搞得我好亂啊!記得!若要載進其它資料時,先開依各檔將資料集先讀進R,在開始寫ui及server的程式,當然後續會介紹如何將資料集自動讀進R中。

我們下一篇見!








無現金支付的反思!

  **購物經歷** - 作者花費大量時間尋找立燈,最終在IKEA購買了一個649元的立燈 - 在IKEA附近停車場遇到只接受無現金支付的情況,被迫註冊並使用Line Pay **無現金支付的觀察** - 作者認為Line Pay作為前端介面,有助於提高停車場付費效率 - 作者預...