R语言—Shiny框架

官方教程:Get Started — Lesson1

学习路线:Start—Build—Improve—Share

中文转载:知乎R-Shiny

Shiny—Server:Shiny—Server教程

Get Started

Lesson 2 Build a user interface

library(shiny)

# Define UI ----
ui <- fluidPage(
  
)

# Define server logic ----
server <- function(input, output) {
  
}

# Run the app ----
shinyApp(ui = ui, server = server)

在所有的Lesson中均使用sidebar layout,若想了解更多的layout,请查看:Shiny Application Layout Guide

任何在HTML中使用的tag attribute都可以在这里使用:

ui <- fluidPage(
  titlePanel("My Star Wars App"),
  sidebarLayout(
    sidebarPanel(),
    mainPanel(
      h2("their first victory against the", align = "center"),
      p("p creates a paragraph of text."),
      p("A new p() command starts a new paragraph. Supply a style attribute to change the format of the entire paragraph.", style = "font-family: 'times'; font-si16pt"),
      strong("strong() makes bold text."),
      em("em() creates italicized (i.e, emphasized) text."),
      br(),
      code("code displays your text similar to computer code"),
      div("div creates segments of text with a similar style. This division of text is all blue because I passed the argument 'style = color:blue' to div", style = "color:blue"),
      br(),
      p("span does the same thing as div, but it works with",
        span("groups of words", style = "color:blue"),
        "that appear inside a paragraph.")

    )
  )
)

关于图片,在文件目录下建立一个www目录,把所有的图片文件都存到这个目录下。

其他的HTML的属性:通过HTML定制UI

Lesson 3 Add control widgets

每个widget函数具有多个参数:

  1. name for the widget:character string,类似于html的id。
  2. a label:就是对widget进行一个解释性的说明,提示文字:prompt?
ui <- fluidPage(
  titlePanel("Basic widgets"),
  
  fluidRow(
    
    column(3,
           h3("Buttons"),
           actionButton("action", "Action"),
           br(),
           br(), 
           submitButton("Submit")),
    
    column(3,
           h3("Single checkbox"),
           checkboxInput("checkbox", "Choice A", value = TRUE)),
    
    column(3, 
           checkboxGroupInput("checkGroup", 
                              h3("Checkbox group"), 
                              choices = list("Choice 1" = 1, 
                                             "Choice 2" = 2, 
                                             "Choice 3" = 3),
                              selected = 1)),
    
    column(3, 
           dateInput("date", 
                     h3("Date input"), 
                     value = "2014-01-01"))   
  ),
  
  fluidRow(
    
    column(3,
           dateRangeInput("dates", h3("Date range"))),
    
    column(3,
           fileInput("file", h3("File input"))),
    
    column(3, 
           h3("Help text"),
           helpText("Note: help text isn't a true widget,", 
                    "but it provides an easy way to add text to",
                    "accompany other widgets.")),
    
    column(3, 
           numericInput("num", 
                        h3("Numeric input"), 
                        value = 1))   
  ),
  
  fluidRow(
    
    column(3,
           radioButtons("radio", h3("Radio buttons"),
                        choices = list("Choice 1" = 1, "Choice 2" = 2,
                                       "Choice 3" = 3),selected = 1)),
    
    column(3,
           selectInput("select", h3("Select box"), 
                       choices = list("Choice 1" = 1, "Choice 2" = 2,
                                      "Choice 3" = 3), selected = 1)),
    
    column(3, 
           sliderInput("slider1", h3("Sliders"),
                       min = 0, max = 100, value = 50),
           sliderInput("slider2", "",
                       min = 0, max = 100, value = c(25, 75))
    ),
    
    column(3, 
           textInput("text", h3("Text input"), 
                     value = "Enter text..."))   
  )
  
)

helptext,lable可以考虑使用;除此之外,在Shiny Widget Gallery中,提供更多的模板。

Lesson 4 Display reactive output

为你的shiny项目添加交互功能!

  1. 在用户界面上添加R对象
  2. 告诉Shiny在server函数中如何构建对象,当代码可以调用窗口值的时候,对象可交互

Shiny为你的用户界面提供了一系列的函数,每个函数指定了一个特别的输出:

Output functionCreates
dataTableOutputDataTable
htmlOutputraw HTML
imageOutputimage
plotOutputplot
tableOutputtable
textOutputtext
uiOutputraw HTML
verbatimTextOutputtext

在sidebarPanel里选择,在mainPanel里输出:

ui <- fluidPage(
  titlePanel("censusVis"),
  
  sidebarLayout(
    sidebarPanel(
      helpText("Create demographic maps with 
               information from the 2010 US Census."),
      
      selectInput("var", 
                  label = "Choose a variable to display",
                  choices = c("Percent White", 
                              "Percent Black",
                              "Percent Hispanic", 
                              "Percent Asian"),
                  selected = "Percent White"),
      
      sliderInput("range", 
                  label = "Range of interest:",
                  min = 0, max = 100, value = c(0, 100))
    ),
    
    mainPanel(
      textOutput("selected_var")
    )
  )
)

交互的控制需要依赖于server函数中的操作:

server <- function(input, output) {
  output$selected_var <- renderText({ 
    "You have selected this"
  })
}

The server function plays a special role in the Shiny process; it builds a list-like object named output that contains all of the code needed to update the R objects in your app. Each R object needs to have its own entry in the list.

You can create an entry by defining a new element for output within the server function, like below. The element name should match the name of the reactive element that you created in the ui.

In the server function below, output$selected_var matches textOutput("selected_var") in your ui.

server 函数在Shiny中非常特别,它创建了一个类似于列表的output对象,该对象包含了所有在app中所有需要被更新的R对象;每个R对象的列表都需要它自己的entry(入口)?你可以在server函数中,通过定义一个新的元素创建一个entry(入口),元素的名字应该与在ui中创建的交互式元素名一致。在上面的server函数中,output$selected_var匹配ui中textOutput("selected_var)。

Each entry to output should contain the output of one of Shiny’s render* functions. These functions capture an R expression and do some light pre-processing on the expression. Use the render* function that corresponds to the type of reactive object you are making.

每个output的entry(入口)应该包括一个Shiny render函数的的输出。这些函数捕捉R的表达式,并且在这些表达式上做一些预先处理。对不同类型的交互对象,应该使用不同的render函数:

render functioncreates
renderDataTableDataTable
renderImageimages (saved as a link to a source file)
renderPlotplots
renderPrintany printed output
renderTabledata frame, matrix, other table like structures
renderTextcharacter strings
renderUIa Shiny tag object or HTML

每个render函数仅接受一个R表达式{},这个表达式可以为文本,或者很复杂的代码。或者为Shiny可以稍后执行的一系列的指令(更新时则执行)。

server <- function(input, output) {
  
  output$selected_var <- renderText({ 
    paste("You have selected", input$var)
  })
  output$slidered_range <- renderText({
    paste("You have chosen a range that goes from ",
          input$range[1], " to ", input$range[2])
    })
}

Lesson 5 Use R scripts and data

在项目目录下建立一个文件夹:data

为了使用percent_map,需要下载1.数据 2.helpers.R,然后安装(由于网站比较慢,我在csdn中上传了资源(免费自取链接))

install.packages(c("maps", "mapproj"))

To use percent_map, we first ran helpers.R with the source function, and then loaded counties.rds with the readRDS function. We also ran library(maps) and library(mapproj).

  • The shinyApp function is run once, when you launch your app(整个shinyApp项目在你运行的时候执行一遍)
  • The server function is run once each time a user visits your app(server函数在每一次有用户进入时执行)
  • The R expressions inside render* functions are run many times. Shiny runs them once each time a user change the value of a widget.(render函数里的东西在任意一个用户交互的时候执行)

从这三条我们可以得出

  • 源脚本,库,数据这些东西,在server函数外,app.R最上头写,Shiny只会执行一遍这些内容;sever函数中的内容在服务器上执行
  • 针对每个用户的内容写在server内,render外,这是每个用户独有的一份对象;类似于session,这个代码run once per user.
  • 用户对每个widget操作,对操作的交互内容放在render函数内(re-run),为了提高效率,需要把不改变的内容放在render外,避免效率低下的问题

根据选择人种,显示相应的percent_map:

server <- function(input, output) {
  output$map <- renderPlot({
    data <- switch(input$var, 
                   "Percent White" = counties$white,
                   "Percent Black" = counties$black,
                   "Percent Hispanic" = counties$hispanic,
                   "Percent Asian" = counties$asian
                   )
    color <- switch(input$var,
                    "Percent White" = "darkgreen",
                    "Percent Black" = "black",
                    "Percent Hispanic" = "darkorange",
                    "Percent Asian" = "darkviolet"
                    )
    legend <- switch(input$var,
                     "Percent White" = "% White",
                     "Percent Black" = "% Black",
                     "Percent Hispanic" = "%Hispanic",
                     "Percent Asian" = "% Asian"
                     )
      
    
    percent_map(var = data, color = color, legend = legend, max = input$range[2], min = input$range[1])
  })
}

更简便的写法:

server <- function(input, output) {
  output$map <- renderPlot({
    args <- switch(input$var,
      "Percent White" = list(counties$white, "darkgreen", "% White"),
      "Percent Black" = list(counties$black, "black", "% Black"),
      "Percent Hispanic" = list(counties$hispanic, "darkorange", "% Hispanic"),
      "Percent Asian" = list(counties$asian, "darkviolet", "% Asian"))
        
    args$min <- input$range[1]
    args$max <- input$range[2]
  
    do.call(percent_map, args)
  })
}

Lesson 6 Use Reactive expressions

通过使用交互式表达式,wow your user,避免不必要的计算!

# Load packages ----
library(shiny)
library(quantmod)

# Source helpers ----
source("helpers.R")

# User interface ----
ui <- fluidPage(
  titlePanel("stockVis"),
  
  sidebarLayout(
    sidebarPanel(
      helpText("Select a stock to examine.

        Information will be collected from Yahoo finance."),
      textInput("symb", "Symbol", "SPY"),
      
      dateRangeInput("dates",
                     "Date range",
                     start = "2013-01-01",
                     end = as.character(Sys.Date())),
      
      br(),
      br(),
      
      checkboxInput("log", "Plot y axis on log scale",
                    value = FALSE),
      
      checkboxInput("adjust",
                    "Adjust prices for inflation", value = FALSE)
    ),
    
    mainPanel(plotOutput("plot"))
  )
)

# Server logic
server <- function(input, output) {
  
  output$plot <- renderPlot({
      data <- getSymbols(input$symb, src = "yahoo",
                         from = input$dates[1],
                         to = input$dates[2],
                         auto.assign = FALSE)

      chartSeries(data, theme = chartTheme("white"),
                  type = "line", log.scale = input$log, TA = NULL)
    })
  
}

# Run the app
shinyApp(ui, server)

这里的renderPlot,在每次widget改变的时候,都会重新加载一次数据(浪费)。

通过使用reactive function,就可以解决这个问题:

dataInput <- reactive({
  getSymbols(input$symb, src = "yahoo",
    from = input$dates[1],
    to = input$dates[2],
    auto.assign = FALSE)
})

output$plot <- renderPlot({    
  chartSeries(dataInput(), theme = chartTheme("white"),
    type = "line", log.scale = input$log, TA = NULL)
})

Reactive表达式缓存值,并且了解什么时候这个值是过时的,第一次运行这个函数的时候,它会把结果(数据)保存在计算机内存里,当下一次调用这个函数的时候,它能不经过任何计算,返回保存的值(数据)。

Reactive表达式只会返回最新的结果,如果reactive表达式知道结果(数据)已经过时,因为widget已改变,这个表达式会重新计算结果,然后返回和保存最新的结果。reactive表达式使用这个新的拷贝直到它过时。

  • A reactive expression saves its result the first time you run it.
  • The next time the reactive expression is called, it checks if the saved value has become out of date (i.e., whether the widgets it depends on have changed).
  • If the value is out of date, the reactive object will recalculate it (and then save the new result).
  • If the value is up-to-date, the reactive expression will return the saved value without doing any computation.

通过这个方式防止Shiny重复运行代码,如果我们改变symb widget,Shiny还会知道input$symb过时了吗,会的,因为Shiny随时跟踪reactive 表达式,一旦它改变,Shiny会重构:

  • an input value in the objects’s render* function changes, or
  • a reactive expression in the objects’s render* function becomes obsolete

不过注意,只能在reactive里和render*里调用reactive表达式,因为只有这两个R函数具有处理reactive output的能力。

Lesson 7 Share your apps

我用的是Shiny—Server,用服务器就好了,比我之前学的的用Java,方便了一万倍!

Build

Introduction to R Markdown

还好之前接触过markdown,相当于把markdown embedded into R语言;

后缀是.Rmd;

R Markdown的优势:

  • knit:您可以knit文件。 .rmarkdown软件包将调用knitr软件包。 knitr将运行文档中的每个R代码块,并将代码结果附加到代码块旁边的文档中。 此工作流程可以节省时间并简化可重复的报告。考虑作者通常如何在报告中包括图形(或表格或数字)。 作者制作图形,将其保存为文件,然后复制并将其粘贴到最终报告中。 此过程依赖于用户自己操作。 如果数据发生变化,那么作者必须重复整个过程以更新图形。(动态文档)在R Markdown范式中,每个报告都包含制作自己的图形,表格,数字等所需的代码。作者可以直接通过重新knit自动更新报告。
  • convert:您可以转换文件。 .rmarkdown软件包将使用pandoc程序将文件转换为新格式。 例如,您可以将.Rmd文件转换为HTML,PDF或Microsoft Word文件。 您甚至可以将文件转换为HTML5或PDF幻灯片。 .rmarkdown将保留原始.Rmd文件中包含的文本,代码结果和格式。通过转换,您可以轻松地在Markdown中完成原始工作。 您可以包括要knit的R代码,并且可以以多种格式共享文档。
rmarkdown::render()

在Rstudio中,使用Knit HTML等按钮执行代码;

注意:RStudio不会从头开始构建PDF和Word文档。 您需要在计算机上安装发行版的Latex才能制作PDF,并需要安装Microsoft Word(或类似程序)来制作Word文件。

Knitr for embedded R code

呈现报告时,knitr将运行代码并将结果添加到输出文件中。 您可以使输出仅显示代码,仅显示结果或同时显示两者。

要将大块R代码嵌入到报表中,请用两行代码包围该代码,每行包含三个反引号。 在第一组反引号之后,包括{r},它会警告knitr您已经包含了一部分R代码。 结果将如下所示

Here's some code
```{r}
dim(iris)
```

eval = FALSE:表示不显示输出结果

echo = FALSE:表示不显示代码

行内代码:

Two plus two equals `r 2 + 2`.

YAML for render parameters

您可以使用YAML header来控制rmarkdown如何显示您的.Rmd文件。 YAML header以键值对来表达,如下所示

---
title: "Untitled"
author: "Garrett"
date: "July 10, 2014"
output: html_document
---

Some inline R code, `r 2 + 2`.

output表示在您调用rmarkdown::render()的时候,决定将您的.Rmd文件转化为何种格式,一共有三种形式:

  • html_document
  • pdf_document
  • word_document

更多的YAML设置,请见:http://rmarkdown.rstudio.com/html_document_format.html

Introduction to interactive documents

An interactive documents:R Markdown文件中包含了Shiny widgets 和 outputs,通过Rmarkdown写报告,但是把它当做app运行。(R Markdown和Shiny的结合)

  1. 在YAML header 添加 runtime: shiny
  2. 在R代码块中添加Shiny widgets和Shiny render函数
---
runtime: shiny
output: html_document
---

### Here are two Shiny widgets

```{r echo = FALSE}
selectInput("n_breaks", label = "Number of bins:",
              choices = c(10, 20, 35, 50), selected = 20)

sliderInput("bw_adjust", label = "Bandwidth adjustment:",
              min = 0.2, max = 2, value = 1, step = 0.2)
```

### ...that build a histogram.

```{r echo = FALSE}
renderPlot({
  hist(faithful$eruptions, probability = TRUE,
       breaks = as.numeric(input$n_breaks),
       xlab = "Duration (minutes)",
       main = "Geyser eruption duration")

  dens <- density(faithful$eruptions, adjust = input$bw_adjust)
  lines(dens, col = "blue")
})
```

运行交互式文档时,rmarkdown会提取代码块中的代码,并将其放入伪server.R文件中。 R Markdown使用markdown文件的html输出作为index.html文件来放置交互性元素。

注意:如果您熟悉R Markdown,则可能希望RStudio将交互式文档的HTML版本保存在您的工作目录中。 但是,这仅适用于静态HTML文档。 每个交互式文档必须由管理该文档的计算机提供。 于是,交互式文档不能作为独立的HTML文件共享。

您可以使用R Markdown创建交互式幻灯片,而仅使用Shiny很难做到这一点。 要创建幻灯片,请在.Rmd文件的YAML前端将输出:html_document更改为输出:ioslides_presentation。 单击“运行文档”时,R Markdown会将您的文档分成幻灯片。每当出现标头或水平标尺(***)时,新的幻灯片就会开始。

更多有关R markdown的使用:https://rmarkdown.rstudio.com/

Build Dashboard

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值