本节为Shiny平台构建与R包开发教程的第一小节。

Getting Started

初识Shiny时,了解其工作机理非常重要。下面的案例展示了一个最简单的Shiny APP的工作机理:

#DO NOT include any non-English characters in Shiny script
library(shiny)
ui <- fluidPage("Hello World!")
server <- function(input, output){}
shinyApp(ui, server)

其运行方式和其他R语言代码没有太大的差别。直接让光标定位在脚本文件中,单击Run或按快捷键Ctrl+Enter将代码逐行运行。ui变量定义了Shiny APP的ui设计,server函数定义了Shiny APP的服务器行为。input参数代表用户向服务器中输入的数据,output代表服务器向用户展示的内容。

当运行shinyApp函数时,Shiny调用图形用户界面(GUI),打开网页。只要网页不被关闭,shinyApp就一直处于运行状态,用户也就无法在Rstudio的命令行窗口运行其他命令。

不要马上急着关闭弹出的GUI。点击“Open in Browser”按钮,按下“(Fn)+F12”按钮,进入浏览器调试模式。如果您了解过HTML+CSS+JS的基本知识,请耐心阅读Box1部分内容,以深刻地理解Shiny是如何生成HTML网页的。这对后续ui排版及CSS设计的深入理解有很好地辅助作用。

Box1 Shiny生成HTML网页的内在机制
进入浏览器调试模式后,打开<head>标签,可以找到<link>引入了bootstrap的css文件,表明Shiny的CSS是基于bootstrap开发的。展开<body>标签,发现类名为container-fluid的一个<div>标签。这表明Shiny中fluidPage函数的功能是向网页中插入一个<div class="container-fluid"></div>。而这一标签的具体样式显然在CSS文件中已被定义了。

退出GUI界面,回到R终端,运行print(ui),同样也可以看到ui变量本质上就是个<div>。再来看一个更复杂的例子。

ui <- fluidPage(titlePanel("title Panel"),sidebarLayout(sidebarPanel("sidebar Panel"),mainPanel("main Panel")    )
)
server <- function(input, output){}
shinyApp(ui, server)

先运行print(ui),发现在fluidPage函数构建的<div class="container-fluid">的基础上,titlePanel函数在内部插入了<h2>标签;siderbarLayout函数插入了<div class="row">标签;sidebarPanelmainPanel函数分别在row标签的div区块中分别插入<div class="col-sm-4"><div class="col-sm-8" role="main">。除此之外,很重要的一点是titlePanel还在网页的<head>标签中插入了<title>标签,即<title>title Panel</title>。因此,对应网页的标签也自动变成了title Panel了。
总之,ui变量在R中存储的仅仅是字符串,但其内部字符的语法遵从HTML语言,在网页端根据HTML语法翻译成对应元素。此后的ui设计案例也可以用同样的方法查看每个函数的作用。

元素布局

最常用的网页内元素布局是将页面划分为不同的“行”和“列”。以Bing为例,若想要“复刻”一个Bing的首页,一种方法是:将网页划分为6行,每一行又可以分为不同数量的列。每一“行”是一个<div class="row">,每一列是嵌套在“行”<div>里面的<div class="column">。因此,在Bing首页中,第一行需要设置6个“列”<div>,第一个<div>放Microsoft的logo以及文字“Microsoft Bing”,一直到最后一个<div>放一个功能选项按钮。第二行只需要一个“列”<div>,并且是空白的。最后一行也只有一个“列”<div>,放置许多版权信息和链接。
图1 ui布局—以Bing为例
这一布局落实到Shiny中就变成:

ui <- fluidPage(fluidRow(column(),column(),column(),column(),column(),column()),fluidRow(column()),fluidRow(column()),fluidRow(column()),fluidRow(column(),column(),column(),column()),fluidRow(column())
)

其中每个column函数填上对应的HTML元素,在R中以遵循HTML语法的字符串形式表示。但问题是,每个“列”<div>的宽度怎么定义?column函数中有width参数,其取值在0~12间,其中12代表与电脑显示屏的宽度相等。若取值为4,相当于这个column产生的区域为电脑显示屏宽度的4/12=1/3。

关于更多的ui页面内布局方式,可以参考以下博客:
https://blog.csdn.net/weixin_27744023/article/details/112742221

之前演示的sidebarLayout在这篇博客中定义为“左右布局”,同样也可以用width参数控制side panel和main panel的宽度;这篇博客中涉及的“分页布局”在实际Shiny APP中也应用较多。如果您还不知道Shiny中server变量定义的语法,您可以将这篇博客的案例代码中将与ui布局无关的函数全部去掉,替换成普通字符串,以理解每个案例的运作机理。

页面布局

无论是bibliometrix包还是Expmeasure包,其Shiny GUI页面顶部都有导航栏(navigation bar)。但fluidPage函数并不能实现这一功能。

R Shiny中最常用的两种页面布局函数是fluidPage(静态页面)和navbarPage(导航页面)。下面的案例非常典型,介绍了如何搭配使用这两个函数构造整个Shiny数据分析平台的ui。

ui.overall <- navbarPage("expmeasures",tabPanel("Home", ui.home),tabPanel("Data", ui.data),navbarMenu("Trend",tabPanel("2D Plot", ui.trend.2D_Plot),tabPanel("3D Plot", ui.trend.3D_Plot),tabPanel("VioPlot", ui.trend.VioPlot)),navbarMenu("Error",tabPanel("Outlier", ui.error.Outlier),tabPanel("Leverage", ui.error.Leverage),tabPanel("Influence", ui.error.Influence)),navbarMenu("Significance",tabPanel("K-function", ui.significance.k),tabPanel("GLMs", ui.significance.GLMs),tabPanel("Residue", ui.significance.residue),tabPanel("Jackknife", ui.significance.jackknife)),navbarMenu("Explantory",tabPanel("ANOVA", ui.explantory.ANOVA),tabPanel("Muti Comp", ui.explantory.muticomp)),navbarMenu("Prediction",tabPanel("Trend", ui.prediction.trend),tabPanel("Spline", ui.prediction.spline),tabPanel("Inverse", ui.prediction.inverse),tabPanel("Simp Mov", ui.prediction.simmov),tabPanel("Krigging", ui.prediction.krigging)),navbarMenu("Uncertainty",tabPanel("TNE", ui.uncertainty.TNE),tabPanel("T/E Simu", ui.uncertainty.TNEsimu)),tabPanel("Quit")
)

您可以运行expmeasure函数,观察Expmeasure包导航栏结构与上述代码的对应关系。navbarPage函数的第一个参数在导航栏的左侧显示;tabPanel函数构造了导航栏中的一个模块,鼠标点击模块时会跳转到对应页面(对应页面的ui被tabPanel函数的第二个参数指定);navbarMenu函数同样也构造导航栏中的一个模块,但鼠标点击该模块时会出现下拉菜单,显示若干子模块。每个子模块又由tabPanel函数构造,tabPanel函数的第二个参数定义了对应页面的ui。

那么,所谓对应页面的ui又应该怎么定义?这里以Expmeasure的HOME页面为例:

ui.home <- fluidPage(sidebarPanel(fluidRow(column(12, align = "center", imageOutput('igem_icon', height = "250px"))),fluidRow(column(12, align = "center", h1("Expmeasure: A tool for part characterization"))),fluidRow(column(12, align = "center", h2("Developed by ZJU-China, 2021"))),width = 12)
)

可见,每个对应页面的ui就是一个fluidPage。至于在fluidPage中要填什么元素,就是“元素布局”应该要考虑的事情。这里HOME页面只放一个Side Bar,让它的宽度占满整个电脑屏幕(width=12)。在Side Bar中放置三行,第一行放一个图片,第二行放一行h1标题文字,第三行放一行h2标题文字。column函数的第一个参数就是width参数,注意这里width=12就不是占满整个电脑屏幕,而是占满整个Side Bar的宽度,因为fluidRow被嵌套在了sidebarPanel里面(如果学过HTML,我们知道嵌在里面的一个div的长宽不会超过它外面的div)。

至此,您已经通过本教程了解到如何设计网页布局,并能设计导航页面和静态页面,在静态页面中插入标题、文字。但您可能马上就有欲望在页面中插入图片,因为这会使网页更好看。

插入图片

事实上,上述代码块已经初步展示了在Shiny页面中插入图片的语法,下面展示完整代码:

ui <- fluidPage(sidebarPanel(fluidRow(column(12, align = "center", imageOutput('igem_icon', height = "250px"))),fluidRow(column(12, align = "center", h1("Expmeasure: A tool for part characterization"))),fluidRow(column(12, align = "center", h2("Developed by ZJU-China, 2021"))),width = 12)
)server <- function(input, output){output$igem_icon <- renderImage({list(src = './expmeasure/R/logo.png')
}   , deleteFile = FALSE)
}shinyApp(ui, server)

上述代码的ui部分中,核心部分是imageOutput函数。该函数的第一个参数指定了图像输出区域的编号。这里编号为"igem_icon"。在server变量中,由"output$igem_icon"识别相应编号,并利用renderImage函数在该区域输出本地路径为’./expmeasure/R/logo.png’的图片。

关于数据输出(包括table、plot、text等)的详细机理将在第四节介绍,图片输出只是服务器输出数据的一种形式。了解图片输出方式后,其他的数据输出形式十分类似。例如输出table只需将imageOutputrenderImage函数组合替换成tableOutputrenderTable即可。

下一篇: Shiny平台构建与R包开发(二)——数据输入


欢迎感兴趣的同行朋友们批评指正。
联系邮箱:hrwu_ecology@163.com

Shiny平台构建与R包开发(一)——ui布局相关推荐

  1. Shiny平台构建与R包开发(七)——Shiny APP部署

    本节展示了如何分享和部署Shiny APP.您可以将开发好的Shiny APP部署在自己的服务器上,或是将其部署在公共的平台(即shinyapps.io)上.这里仅分享后者.对于如何将Shiny AP ...

  2. Shiny平台构建与R包开发(五)——ui美化

    本节简单地向读者介绍Shiny APP中ui的美化方法. shinythemes 利用shinythemes包,您可以选择不同的bootstrap风格,并将其应用到Shiny APP中. 安装完shi ...

  3. Shiny平台构建与R包开发(四)——按钮与响应事件

    作为Shiny平台构建与R包开发教程的第四小节,本节向读者进一步强调Shiny server的工作机理,并由此设计按钮点击事件. Shiny server工作机理与问题 前面的几个小节已经向读者初步解 ...

  4. Shiny平台构建与R包开发(三)——数据输出

    作为Shiny平台构建与R包开发教程的第三小节,本节向读者展示如何利用Shiny server输出自己想要的数据,包括Rplot.Table.Text等信息. 数据输出机制 仍以上一节的案例为基础: ...

  5. Shiny平台构建与R包开发(二)——数据输入

    作为Shiny平台构建与R包开发教程的第二小节,本节向读者介绍如何利用Shiny server处理用户输入的各种信息.这些信息既包括用户向Shiny上传的数据集,也包括用户对Shiny页面的各种控件( ...

  6. Shiny平台构建与R包开发

    Introduction 在数据库网页搭建教程中已经提到,数据分析决策平台的搭建十分重要.数据库网页是数据分析决策平台的重要表现形式之一,能够很好地将大量数据或其分析结果公开展示,并能提供数据下载.统 ...

  7. R包开发每日中国天气

    R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大. R语言作为统计学一门语言,一直在小众领域闪耀着光芒.直到大数据的爆发,R语言变成了一门炙手可 ...

  8. R · R 包开发 | 保姆级教程

    R · R 包开发 一般在初始阶段我们都是使用别人的函数来完成大部分任务,那些函数大多来自 R 标准安装的包或者可以从 CRAN 下载的包. 安装新的包可以拓展 R 的功能.比如说,安装 ggplot ...

  9. iOS8开发~UI布局(二)storyboard中autolayout和size class的使用详解

    一.概要:前一篇初步的描述了size class的概念,那么实际中如何使用呢,下面两个问题是我们一定会遇到的: 1.Xcode6中增加了size class,在storyboard中如何使用? 2.a ...

最新文章

  1. Consumer is not subscribed to any topics
  2. 十、Sumif 函数
  3. DIY Virtual Wall for Roomba – Part One
  4. ZBrush常用快捷键
  5. python职业发展规划书范文_职业生涯规划书范文 3篇
  6. Angular CLI: 全局脚本
  7. Ubuntu下编译运行C#——mono tools
  8. 微博中的长链接与短链接
  9. mysql面试题 真的很不错
  10. r语言 tunerf函数_R语言非参时间序列(六):波动脉冲响应(VIR)中的关键公式推导...
  11. java俄罗斯方块程序设计报告_java课程设计实验报告俄罗斯方块
  12. 关于空间风靡的心理入侵小游戏浅析
  13. tablewidget设置输入数字_【办税辅导】 增值税发票开票软件(税务UKey版)登录及设置...
  14. 解决Unresolved external ‘AlphaBlend‘ referenced的办法
  15. 科学计算机中log,科学计算器的科学用法.docx
  16. CNVD国家区块链漏洞库漏洞通报
  17. Oracle连接pg,pg连接oracle.sql
  18. MacBook Pro电脑一键切换输入法
  19. qduoj 生化危机
  20. JavaScript基础题目(附答案)

热门文章

  1. 什么是接口幂等性?为什么会产生这个问题?如何保证接口幂等性?
  2. 服务治理治什么,10张图告诉你答案
  3. 程序员如何打破35岁魔咒
  4. 大白话详解5种网络IO模型
  5. 面试题:jdk那些类的底层实现使用过位运算,并且给你印象最深?
  6. 十二张图详解Redis的数据结构和对象系统
  7. 50强人工智能面试问题与解答
  8. 如果有一天程序员再也不忙了
  9. 共抗疫情,飞书助力学校、企业等组织机构高效远程协作
  10. 打通Devops的Scrum敏捷工具