开发一个Rshiny应用(基础)

Introduction

Shiny 是一个 R 包,可轻松地直接从 R 构建交互式 Web 应用程序。还可以在网页上托管独立应用程序或将它们嵌入 R Markdown 文档或构建仪表板,还可以使用 CSS 主题、html 小部件和 JavaScript 操作扩展您的 Shiny 应用程序。

#first app
library(shiny)
ui <- fluidPage("Hello, world!"
)
server <- function(input, output, session) {
}
shinyApp(ui, server)

整个app可分为两个部分,ui与sever,可以认为是前端与后端的关系,Rshiny提供了很多内置的小组件帮我们将前后端联系起来,非常方便好用。只需要有一点点的HTML/CSS/Javascript的知识就可以设计出更好看的界面和更多有趣的交互。

这里是shiny的记忆手册,浓缩了大部分的操作。

Methods

UI设计

Layout

最基础的布局就是sidebarLayout,可以分成sidebarPanel,mainPanel两个部分。

ui <- fluidPage(titlePanel("title panel"),sidebarLayout(sidebarPanel("sidebar panel"),mainPanel("main panel"))
)

可以通过将内容放在 *Panel 函数中来向Shiny 应用程序添加内容,shiny提供了R代码方便插入HTML (Table 1),更多标签可以查看tag-glossary。

Table 1: shiny function HTML5 equivalent creates
shiny function HTML5 equivalent creates
p <p> A paragraph of text
h1 <h1> A first level header
h2 <h2> A second level header
h3 <h3> A third level header
h4 <h4> A fourth level header
h5 <h5> A fifth level header
h6 <h6> A sixth level header
a <a> A hyper link
br <br> A line break (e.g. a blank line)
div <div> A division of text with a uniform style
span <span> An in-line division of text with a uniform style
pre <pre> Text ‘as is’ in a fixed width font
code <code> A formatted block of code
img <img> An image
strong <strong> Bold text
em <em> Italicized text
HTML NA Directly passes a character string as HTML code
Control widgets

这些是常用shiny内置的小控件,提供一种向 Shiny serve发送消息的方式。

Table 2: standard Shiny widgets
function widget
actionButton Action Button
checkboxGroupInput A group of check boxes
checkboxInput A single check box
dateInput A calendar to aid date selection
dateRangeInput A pair of calendars for selecting a date range
fileInput A file upload control wizard
helpText Help text that can be added to an input form
numericInput A field to enter numbers
radioButtons A set of radio buttons
selectInput A box with choices to select from
sliderInput A slider bar
submitButton A submit button
textInput A field to enter text

可以想想怎么获取更多控件,比如一个color panel等等。

更多:

使用 textInput() 收集少量文本,使用 passwordInput()3 收集密码,使用 textAreaInput() 收集文本段落。

要收集数值,请使用 numericInput() 创建一个受约束的文本框或使用 sliderInput() 创建一个滑块。如果您为 sliderInput() 的默认值提供一个长度为 2 的数值向量,您将得到一个具有两端的“范围”滑块。

使用 dateInput() 收集一天或使用 dateRangeInput() 收集两天的范围。这些提供了一个方便的日历选择器,并且诸如 datesdisabled 和 daysofweekdisabled 之类的附加参数允许您限制有效输入的集合。

有两种不同的方法允许用户从一组预先指定的选项中进行选择:selectInput()(还可以设置 multiple = TRUE 以允许用户选择多个元素)和 radioButtons(); 可以使用checkboxGroupInput()形成多选。

ui <- fluidPage(textInput("name", "What's your name?"),passwordInput("password", "What's your password?"),textAreaInput("story", "Tell me about yourself", rows = 3)
)ui <- fluidPage(numericInput("num", "Number one", value = 0, min = 0, max = 100),sliderInput("num2", "Number two", value = 50, min = 0, max = 100),sliderInput("rng", "Range", value = c(10, 20), min = 0, max = 100)
)ui <- fluidPage(dateInput("dob", "When were you born?"),dateRangeInput("holiday", "When do you want to go on vacation next?")
)animals <- c("dog", "cat", "mouse", "bird", "other", "I hate animals")
ui <- fluidPage(selectInput("state", "What's your favourite state?", state.name),radioButtons("animal", "What's your favourite animal?", animals),checkboxGroupInput("animal", "What animals do you like?", animals)
)

让用户使用 actionButton() 或 actionLink() 执行操作,可以使用“btn-primary”、“btn-success”、“btn-info”、“btn-warning”或“btn-danger”之一使用类参数自定义外观,使用“btn-lg”、“btn-sm”、“btn-xs”更改大小,可以使用“btn-block”使按钮跨越它们嵌入的元素的整个宽度。

ui <- fluidPage(fluidRow(actionButton("click", "Click me!", class = "btn-danger"),actionButton("drink", "Drink me!", class = "btn-lg btn-success")),fluidRow(actionButton("eat", "Eat me!", class = "btn-block"))
)

连接sever

general
  1. 添加输出对象在ui中

Shiny 提供了一系列函数,可以将 R 对象转换为用户界面的输出。每个函数创建特定类型的输出。

Table 3: output R objects family
Output function Creates
dataTableOutput DataTable
htmlOutput raw HTML
imageOutput image
plotOutput plot
tableOutput table
textOutput text
uiOutput raw HTML
verbatimTextOutput text
  1. 编写构建R对象的代码在serve中
Table 4: render R objects family
render function creates
renderDataTable DataTable
renderImage images (saved as a link to a source file)
renderPlot plots
renderPrint any printed output
renderTable data frame, matrix, other table like structures
renderText character strings
renderUI a Shiny tag object or HTML
  1. 使用input,output连接

以下代码就可以将selectInput选择的值var通过input$var的形式传递到renderText(),再render成output$selected_var的形式,最后通过textOutput()输出到ui界面。

library(shiny)ui <- fluidPage(titlePanel("censusVis"),sidebarLayout(sidebarPanel(selectInput("var", label = "Choose a variable to display",choices = c("Percent White", "Percent Black","Percent Hispanic", "Percent Asian"),selected = "Percent White")),mainPanel(textOutput("selected_var")))
)server <- function(input, output) {output$selected_var <- renderText({ paste("You have selected", input$var)})
}shinyApp(ui, server)

更多:

使用 textOutput() 输出常规文本,使用 verbatimTextOutput() 输出固定代码和控制台输出。
renderText() 将结果组合成一个字符串,通常与 textOutput() 配对
renderPrint() 打印结果,就像您在 R 控制台中一样,并且通常与 verbatimTextOutput() 配对。

tableOutput() 和 renderTable() 呈现静态数据表,同时显示所有数据。
dataTableOutput() 和 renderDataTable() 呈现一个动态表,显示固定数量的行以及用于更改哪些行可见的控件。
tableOutput() 对于小型、固定的摘要(例如模型系数)最有用;如果您想向用户公开完整的数据框,则 dataTableOutput() 是最合适的。

默认情况下,plotOutput() 将占据其容器的整个宽度(稍后会详细介绍),并且高度为 400 像素。您可以使用高度和宽度参数覆盖这些默认值。我们建议始终设置 res = 96,因为这将使您的 Shiny 图与您在 RStudio 中看到的尽可能接近。

reactive expressions

This difference between commands and recipes is one of the key differences between two important styles of programming:

In imperative programming, you issue a specific command and it’s carried out immediately. This is the style of programming you’re used to in your analysis scripts: you command R to load your data, transform it, visualise it, and save the results to disk.

In declarative programming, you express higher-level goals or describe important constraints, and rely on someone else to decide how and/or when to translate that into action. This is the style of programming you use in Shiny.

Shiny 中声明式编程的优势之一是它允许应用程序非常懒惰。 Shiny 应用程序只会执行更新您当前可以看到的输出控件所需的最少工作量,优点是快速,缺点是如果你不运行所有代码,可能不会发现错误。

反应式表达式比常规 R 函数更聪明。它们缓存值并知道它们的值何时会变。第一次运行反应式表达式时,表达式会将其结果保存在计算机的内存中。下次调用反应式表达式时,它可以返回保存的结果而不进行任何计算(这将使您的应用程序更快)。

如果反应式表达式知道结果是最新的,它只会返回保存的结果。如果反应式表达式得知结果已过时(因为小部件已更改),则表达式将重新计算结果。然后它返回新结果并保存一个新副本。反应式表达式将使用这个新副本,直到它也变得过时为止。
让我们总结一下这种行为:

  1. 反应式表达式会在您第一次运行时保存其结果。

  2. 下次调用反应式表达式时,它会检查保存的值是否已过时(即,它所依赖的小部件是否已更改)。

  3. 如果该值已过期,反应对象将重新计算它(然后保存新结果)。

  4. 如果该值是最新的,反应式表达式将返回保存的值而不进行任何计算。

建议把文件导入等不需要每次更新的代码放在reactive里。

在 Shiny 中,应该考虑一个规则:每当复制和粘贴一次东西时,就应该考虑将重复的代码提取到一个反应表达式中,因为反应式表达式不仅让人类更容易理解代码,它们还提高了 Shiny 高效重新运行代码的能力。

考虑以下代码,reactive()确保只有在改变n或lambda时才会重新计算:

library(ggplot2)freqpoly <- function(x1, x2, binwidth = 0.1, xlim = c(-3, 3)) {df <- data.frame(x = c(x1, x2),g = c(rep("x1", length(x1)), rep("x2", length(x2))))ggplot(df, aes(x, colour = g)) +geom_freqpoly(binwidth = binwidth, size = 1) +coord_cartesian(xlim = xlim)
}ui <- fluidPage(fluidRow(column(3, numericInput("lambda1", label = "lambda1", value = 3),numericInput("lambda2", label = "lambda2", value = 5),numericInput("n", label = "n", value = 1e4, min = 0)),column(9, plotOutput("hist")))
)
server <- function(input, output, session) {x1 <- reactive(rpois(input$n, input$lambda1))x2 <- reactive(rpois(input$n, input$lambda2))output$hist <- renderPlot({freqpoly(x1(), x2(), binwidth = 1, xlim = c(0, 40))}, res = 96)
}shinyApp(ui,server)

控制reactive行为:

  1. 计时器
    reactiveTimer() 是一个响应式表达式,它依赖于隐藏的输入:当前时间。
    将server里的reactive修改成下列形式可以让图形每500ms刷新一次。
server <- function(input, output, session) {timer <- reactiveTimer(500)x1 <- reactive({timer()rpois(input$n, input$lambda1)})x2 <- reactive({timer()rpois(input$n, input$lambda2)})output$hist <- renderPlot({freqpoly(x1(), x2(), binwidth = 1, xlim = c(0, 40))}, res = 96)
}
  1. 点击刷新
    当你的serve运行一次需要庞大计算和时间时,可能希望要求用户通过单击按钮来选择执行昂贵的计算。这是 actionButton() 的一个很好的用例:

并且我们需要 eventReactive(),它有两个参数:第一个参数指定依赖什么,第二个参数指定计算什么。

修改ui和serve,添加了按键,用户点击按键即可出现新的模拟结果。

ui <- fluidPage(fluidRow(column(3, numericInput("lambda1", label = "lambda1", value = 3),numericInput("lambda2", label = "lambda2", value = 5),numericInput("n", label = "n", value = 1e4, min = 0),actionButton("simulate", "Simulate!")),column(9, plotOutput("hist")))
)
server <- function(input, output, session) {x1 <- eventReactive(input$simulate, {rpois(input$n, input$lambda1)})x2 <- eventReactive(input$simulate, {rpois(input$n, input$lambda2)})output$hist <- renderPlot({freqpoly(x1(), x2(), binwidth = 1, xlim = c(0, 40))}, res = 96)
}

observeEvent() 与 eventReactive() 非常相似。它有两个重要的参数:eventExpr 和 handlerExpr。第一个参数是要依赖的输入或表达式;第二个参数是将要运行的代码。例如,对 server() 的以下修改意味着每次更新该名称时,都会向控制台发送一条消息:

ui <- fluidPage(textInput("name", "What's your name?"),textOutput("greeting")
)server <- function(input, output, session) {string <- reactive(paste0("Hello ", input$name, "!"))output$greeting <- renderText(string())observeEvent(input$name, {message("Greeting performed")})
}
file up/download

使用fileInput在ui中上传文件后,得到的input是一个列表,其中的datapath是文件上传后的路径,需要使用read.csv等函数读取file$datapath。

ui <- fluidPage(sidebarLayout(sidebarPanel(fileInput("file1", "Choose CSV File", accept = ".csv"),checkboxInput("header", "Header", TRUE)),mainPanel(tableOutput("contents")))
)server <- function(input, output) {output$contents <- renderTable({file <- input$file1ext <- tools::file_ext(file$datapath)req(file)validate(need(ext == "csv", "Please upload a csv file"))read.csv(file$datapath, header = input$header)})
}shinyApp(ui, server)

您可以让用户使用 downloadButton() 或 downloadLink() 下载文件。这些都需要服务器功能中的新技术,因此我们将在第 9 章中回过头来讨论。

Share

文件形式

任何拥有 R 的人都可以运行Shiny 应用程序,分享你的app.R 文件副本,以及您的应用程序中使用的任何补充材料(例如,www 文件夹或 helpers.R 文件)即可,最好写上代码运行的依赖包安装代码。

  • runUrl() will download and launch a Shiny app straight from a weblink.
  • runGitHub( "<your repository name>", "<your user name>")

网页形式

上述方法要求用户在他们的计算机上安装 R 和 Shiny。但如果我们自己搭建好了服务器,也可以直接用浏览器使用我们的APP。

  1. Shinyapps.io

将 Shiny 应用程序转换为网页的最简单方法是使用 shinyapps.io,这是 RStudio 为 Shiny 应用程序提供的托管服务。
2. Shiny Server

  1. RStudio Connect

Reference

官方教程:Shiny Learning Resources

参考书:Mastering Shiny

关注公众号,获取最新推送

关注公众号 ‘bio llbug’,获取最新推送。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1425362.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

使用主机NS记录在cPanel如何添加解析

近期我之前购买了Hostease的域名&#xff0c;并且本身也使用了Hostease的Linux虚拟主机产品&#xff0c;当时时联系咨询了Hostease技术支持帮助操作了域名解析指向了主机&#xff0c;他们当时是将域名默认的4组DNS修改为所属Linux虚拟主机提供的NS记录,但是我现在想要添加我购买…

OpenHarmony上移植memtester

1. 下载源码&#xff1a; wget https://pyropus.ca./software/memtester/old-versions/memtester-4.6.0.tar.gz 2. 解压并指定交叉编译方式 解压 tar -xvf memtester-4.6.0.tar.gz 修改conf-cc和conf-ld&#xff0c;指定交叉编译方式 conf-cc conf-ld 3. 编译 直接运行m…

PWM 什么是PWM?

1. 什么是PWM&#xff1f; PWM是Pulse Width Modulation的缩写&#xff0c;中文是脉冲宽度调制。 是利用微处理器的数字输出来对模拟电路进行控制的一种技术。 2. 面积等效原理 2.1. 什么是面积等效原理&#xff1f; 冲量相等而形状不同的窄脉冲施加在惯性环节上时&#xf…

刷屏一天GPT-4o,发现GPT4用的都还不熟练?戳这儿

以ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diffusion、星火大模型、文心一言、千问为代表AI大语言模型带来了新一波人工智能浪潮&#xff0c;可以面向科研选题、思维导图、数据清洗、统计分析、高级编程、代码调试、算法学习、论文检索、写作、翻译、润色、文献辅助…

js积累一(ipv4正则校验+弹窗方式)

1. ipv4地址&#xff0c;点分十进制的校验 var regexIP /^((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))$/; if(strRegex.test(ip)) //true: 通过 2. 三种弹窗方式: alert()&#xff1b;confirm()&#xff1b; prompt() 1&a…

SUBMIT调用COOIS工序报表获取运行结果后发送ZIP压缩文件

1、SUBMIT调用COOIS报表获取报表结果 2、根据布局格式整理Excel的栏位数据 3、把Excel压缩ZIP 4、发送邮件 运行效果&#xff1a; ************************************************************************ * 程 序 名&#xff1a; * 程序描述&#xff1a;调用COOIS工序…

【SVG 生成系列论文(五)】Diffvg 矢量图生成的开山之作 —— MIT 与 Adobe 合作论文

SVG 生成系列论文&#xff08;一&#xff09; 和 SVG 生成系列论文&#xff08;二&#xff09; 分别介绍了 StarVector 的大致背景和详细的模型细节。SVG 生成系列论文&#xff08;三&#xff09;和 SVG 生成系列论文&#xff08;四&#xff09;则分别介绍实验、数据集和数据增…

软考--试题六--命令模式(Command)

命令模式(Command) 意图 将一个请求封装为一个对象&#xff0c;从而使得可以用不同的请求对客户进行参数化&#xff1b;对请求排队或记录请求日志&#xff0c;以及支持可撤销的操作。 结构 适用性 1、抽象出待执行的动作以参数化某对象 2、在不同的时刻指定、排列和执行请求…

[牛客网]——C语言刷题day3

答案&#xff1a;A 解析&#xff1a; A.表示将数组a的首地址赋值给指针变量p B.将一个int型变量直接赋值给一个int型的指针是不行的 C.道理同B D.j2是一个右值&#xff0c;右值是不能进行取地址操作的 #include <iostream> using namespace std;#define N 7 int fun…

基于DEXPI标准的xml转成svg图片的测试

通过对java代码的一顿反编译&#xff0c;这个功能逐渐实现了。也打了日志&#xff0c;通过编码实现了svg的视图的裁剪大小。选择xml文件然后选择文件夹&#xff0c;程序自动进行转换&#xff0c;最后生成svg文件。 最后的xml转换后的成品如下图&#xff1a; 通过与达美盛的工具…

Linux(七) 动静态库

目录 一、动静态库的概念 二、静态库的打包与使用 2.1 静态库的打包 2.2 静态库的使用 三、动态库的打包与使用 3.1 动态库的打包 3.2 动态库的使用 3.3 运行动态库的四种方法 四、总makefile 一、动静态库的概念 静态库&#xff1a; Linux下&#xff0c;以.a为后缀的…

Sam Blackshear谈Move如何赋能开发者

Move编程语言提供了直观的编码体验&#xff0c;让开发者能够快速上手。Mysten Labs的联合创始人兼CTO Sam Blackshear创建了Move&#xff0c;这是一种用于编写智能合约的语言&#xff0c;更像传统编程语言&#xff0c;如JavaScript或Rust。 https://youtu.be/iYe_hG8Mzx8 视频…

Spring MVC(响应 + 状态码)

文章目录 一、RestController VS Controller VS ResponseBody1.1 关于元注解1.2 Controller1.3 ResponseBody1.4 RestController 二、响应2.1 Spring 对于响应的设置2.2 返回静态页面2.3 返回HTML代码片段2.4 返回JSON2.5 设置HTTP状态码2.6 设置响应部分的Header 二、状态码2.…

小红书孕妇宝妈暴力拉新玩法,每日两小时,单日收益500+

哎呀&#xff0c;你好呀&#xff0c;亲爱的小伙伴们&#xff01;我今天心血来潮&#xff0c;想和你们分享一个超级棒的方法&#xff0c;这个方法我亲自试过&#xff0c;超级有效&#xff01;就是在小红书上针对孕妇和宝妈们进行引流的方法。听起来是不是很有趣呀&#xff1f;&a…

Excel表格内容误删未保存怎么找回?5种XLS文件恢复有效方法

在繁忙的工作中Excel表格作为数据处理的重要工具&#xff0c;承载了众多关键信息。然而误删未保存的Excel内容往往让人措手不及。今天我将为大家分析Excel表格内容误删未保存的可能原因&#xff0c;并提供五个免费实用的解决方案&#xff0c;助你轻松找回误删的XLS文件数据。 一…

贝努利贝叶斯算法

基本用法 完整代码&#xff1a; from sklearn.naive_bayes import BernoulliNB from sklearn.datasets import make_blobs from sklearn.model_selection import train_test_split# 生成数据 X, y make_blobs(n_samples500, centers5, random_state8) X_train, X_test, y_tr…

什么是蜜罐,在当前网络安全形势下,蜜罐能提供哪些帮助

在当前的互联网时代&#xff0c;网络安全威胁日益严峻&#xff0c;攻击手段层出不穷。为了应对这些威胁&#xff0c;网络安全专家们不断探索新的防御手段&#xff0c;在过去的几年里&#xff0c;一种更加积极主动的网络安全方法正在兴起。蜜罐技术便是这样一种备受瞩目的主动防…

打包conda环境的两种方法:conda env export和Conda-Pack

打包conda环境的两种方法&#xff1a;conda env export和Conda-Pack 搭建项目环境可能是整个开发过程中最让人头疼的部分了。如何把我们辛辛苦苦搭建的环境打包起来&#xff0c;万一环境崩了还能迅速恢复&#xff0c;或者让别人能轻松地复制同样的设置呢&#xff1f; 今天&am…

数仓架构之为什么要进行数仓分层

数仓分层这个概念想必大家都很熟悉&#xff0c;不管是在实际的开发工作当中会用的&#xff0c;还是在面试官面试你的时候会问到&#xff1a;你之前的项目是按照什么分层的&#xff0c;分哪几层&#xff0c;数仓分层有什么好处&#xff0c;举个栗子说说。 简而言之&#xff0c;…

[Cocos Creator 3.5赛车游戏]第3节 新建项目

环境已经配置好&#xff0c;现在您将真正的开始开发您的项目&#xff0c;开发项目的第一步是新建项目。所以现在请关闭上一个步骤打开的Cocos Creator窗口&#xff0c;回到CocosDashboard&#xff0c;点击“新建”按钮&#xff1a; 选择“模板”选项卡&#xff0c;因为您即将开…