搜索
查看: 5041|回复: 2

Shiny基础学习

[复制链接]

29

主题

131

帖子

1208

积分

金牌会员

Rank: 6Rank: 6

积分
1208
发表于 2017-4-28 17:17:32 | 显示全部楼层 |阅读模式
本帖最后由 anlan 于 2017-5-1 23:47 编辑

Learning Shiny基础篇
在Rstudio上,可以先搭建一个最简单的shiny框架:
library(shiny)ui <- fluidPage()server <- function(input, output) {}shinyApp(ui = ui, server = server)
ui表示shiny的界面,server则表示执行的程序app。
我们除了可以将ui和server简单的写在一个app.R中(如上面所示),还可以将两者分别写入两个文件ui.R、server.R中。
R将html的标签都封装到tags中,可以通过?tags查看h1()、strong()、em()等用法,因此有类似的用法div("this is blue", style = "color: blue;")
UI部分
  • 添加title
    fluidPage(      titlePanel("BC Liquor Store prices") )
  • 添加布局(简单的布局)
    ui <- fluidPage(       titlePanel("BC Liquor Store prices"),       sidebarLayout(         sidebarPanel("our inputs will go here"),         mainPanel("the results will go here")       ) )
    注意每个函数后面需要逗号进行隔开
  • 标准shiny部件
    actionButton -> 执行按钮 submitButton -> 提交按钮 checkboxGroupInput -> 一组复选框 checkInput -> 一个单一复选框 dataInput -> 一个日期选择器 dataRangeInput -> 时间范围选择器 fileInput 上传文件 helpText -> 帮助文档 numericInput -> 输入数值 radioButtons -> 单选按钮 selectInput -> 可选择的待选盒 sliderInput -> 滑动条 textInput -> 输入文本
    如:
    checkboxInput("checkbox", label="Choice A", value = TRUE)   
    checkbox为inputID, Choice A为部件名称, value为的默认值,如果点了这个按钮则表示输入“TRUE”
    ```sliderInput(“priceInput”, “Price”, min = 0, max = 100,
                          value = c(25, 40), pre = "$")
       )```
    min为sliderInput所要设定的最小值,max则为最大值,pre为在值前面添加的符号,在条形框中可以在范围内任意选择两个值,一个最大值,一个最小值
    ```radioButtons(“typeInput”, “Product type”,
         choices = c("BEER", "REFRESHMENT", "SPIRITS", "WINE"),     selected = "WINE")```  
    choices为选择的按钮值,selected为传输的默认值,选择choices中的一个,则表示将这个值输入到server中执行
    ```selectInput(“countryInput”, “Country”,
         choices = c("CANADA", "FRANCE", "ITALY"))```  
    出现一个下拉框,可以选择choices中的任意一个作为输入值
    将以上连起来放置在sidebarLayout()就是多个的shiny部件的集合体
  • 除了输入的展现形式外,在UI界面还有一个输出的展现形式
    类似于inputId,outputId也需要唯一。函数需要可以写在mainPanel()中,也就是界面的右半边
  • 添加图片在UI界面
    img(src = 'image.png')
    注:图片一般是放在与ui.R以及server.R同目录下的www文件夹内。如果是RStudio中执行的话,可以将图片放在R目录下library\shiny\www内(具体路径因人而异)

Server部分
Server函数主要负责将inputs转变为outputs展现在shiny app上,因此必须有input and output。input就是通过部件读入的values,output则是你将input转化并展现的values。
  • 构建一个output
    首先需要在UI中有个输出的定义,如:
    ```mainPanel(plotOutput("coolplot"))```
  • 然后在server中将部件中的priceInput的value输入,并以plot图展示在”coolplot”中,因为在UI中使用的是plotOutput,所以在server中要使用对应的renderPlot,并将plot放置在renderPlot函数中。
    output$coolplot <- renderPlot({       plot(rnorm(input$priceInput[1])) })
    每个输出都要有个唯一的outputID,这里就是指”coolplot”

  • 我们也可以在shiny app中调用其他包,比如ggplot来作图
    output$coolplot <- renderPlot({       ggplot(bcl, aes(Alcohol_Content)) +         geom_histogram() }) ###bcl是读入的数据框###
  • 除了plot还有常用的table output
    output$results <- renderTable({})

Reactivity部分
Shiny app 能够根据input数据即时改变output数据,这是依靠reactive程序来实现的
  • 除了render*函数,还有另外两个常用的的函数reactive({})和observe({})
    observe(print(input$priceInput))  
    他会输出priceInput值,并且随着部件中priceInput值的变化而变化,输出在console上。如果不加observe,直接print会报错。这种输出方式也是很好的一种排错的方法之一
  • observe({})与reactive({})的区别在于后者可以返回value,前者在于展现value(在console),如:
       priceDiff <- reactive({          diff(input$priceInput)     })     observe({ print(priceDiff()) }) ###注意这里用的是priceDiff(),而不是priceDiff
    因此我们可以将一些R运算放置在reactive中,以减少一些重复的代码。比如一些既在renderPlot({})出现也在renderTable({})出现的运算,可以通过reactive({})来整合成一个reactive变量,然后在后续render*中调用即可

使用uiOutput()创建动态UI元素
  • 一般来说,我们在UI创建的input在shiny app运行前就固定了,但如果你想通过一个input来改变另外一个input,则可以使用uiOutput()来创建动态的input,uiOutput()与之对应在server的是renderUI
    ui <- fluidPage(       numericInput("num", "Maximum slider value", 5),       uiOutput("slider") ) server <- function(input, output) {       output$slider <- renderUI({         sliderInput("slider", "Slider", min = 0,             max = input$num, value = 0)       })     } shinyApp(ui = ui, server = server)
    可以看到,在ui中,已用uiOutput()代替之前原来的sliderInput(),然后在renderUI()设置了一个新的sliderInput(),其值是随着numericInput()的改变而改变,这是一种很常用的表现形式。
  • 使用uiOutput时还要注意一点其运行流程的顺序。比如,如果在server中使用renderUI,然后在其后就要调用renderUI所产生的value,这样是error的。因为renderUI产生的value还需返回到UI中才能被server里的后续函数调用,所以我们需要自行增加判断语句来识别,以过滤掉这error,尽管这个error不会对整个app的运行造成阻碍。
  • 如果我们已经固定了某个UI Input,然后希望在后续又能对其进行修改,则可以使用Input所对应的update*input来修改上述参数,如:
    ui <- fluidPage(       sliderInput("slider", "Move me", value = 5, 1, 10),       numericInput("num", "Number", value = 5, 1, 10) ) server <- function(input, output, session) {       observe({         updateNumericInput(session, "num", value = input$slider)       }) } shinyApp(ui = ui, server = server)
    通过上述代码,我们即可在UI部件numicInput中手动修改参数,也可以通过修改sliderInput中的value来更新numericInput中的value

[size=0em]​


上述内容均来自http://deanattali.com/blog/building-shiny-apps-tutorial/,该教程写的非常详细非常好,很适合新手入门理解,以上内容只是个人的理解总结,详细教程请看原文,语言简单易懂。
排版似乎不行。。贴个有道笔记的链接。。
http://note.youdao.com/share/?id=5a2f8c1230798016dcaf075ca17d574f&type=note

回复

使用道具 举报

634

主题

1182

帖子

4030

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4030
发表于 2017-4-28 22:33:55 | 显示全部楼层
直接贴markdown的源码,然后用chrome的markdownhere这个插件把内容格式化一下,会不会好一点呢,试试看
你这个问题很复杂,需要打赏,请点击 http://www.bio-info-trainee.com/donate 进行打赏,谢谢
回复 支持 反对

使用道具 举报

29

主题

131

帖子

1208

积分

金牌会员

Rank: 6Rank: 6

积分
1208
 楼主| 发表于 2017-5-1 23:45:01 | 显示全部楼层
Jimmy 发表于 2017-4-28 22:33
直接贴markdown的源码,然后用chrome的markdownhere这个插件把内容格式化一下,会不会好一点呢,试试看 ...

试了下,用这个办法,排版没问题,就是渲染后有代码框,但论坛显示不了代码框
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|生信技能树 ( 粤ICP备15016384号  

GMT+8, 2019-10-21 09:16 , Processed in 0.036607 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.