内容简介:继续整理shiny的几个用法最近遇到的一个问题:Shiny的download本质是可以下载任何形式的文件,如表格、图片等等;shiny的官网介绍
继续整理shiny的几个用法
Download two or more plots in one download button
最近遇到的一个问题: 如何在Shiny上通过download按钮同时下载多张图片 。网上也有人提了相同的问题,但是没有给出合适的解决办法
Shiny的download本质是可以下载任何形式的文件,如表格、图片等等;shiny的官网介绍 http://shiny.rstudio.com/articles/download.html
中只提了常规的用法。经过我多次尝试,基本猜测shiny的 downloadHandler
一次点击只能下载一个对象(因为对于网页设计中,一次点击确实只能下载一个对象)
因此转化下思路,我可以将多个图片先保存到一个临时文件夹中,然后压缩后再通过shiny下载
网上查了下,也有人用这个方法来下载多个文件压缩后的压缩包,如 Shiny: download zip archive
现在模仿下就很简单了(将图片先存在 p
列表中,接着用 tempdir()
建个临时文件夹,然后用 ggsave
保存图片,最后用 zip
压缩):
output$download_plot <- downloadHandler( filename = function(){ paste0("plots", ".zip") }, # contentType = "image/png", content = function(file){ fs <- c() tmpdir <- tempdir() setwd(tempdir()) for(i in 1:length(var_name)) { filelist <- paste0(var_name[i], ".png") g <- p[[i]] fs <- c(fs, filelist) ggsave(filename = filelist, plot = g, device = "png", width = 16, height = input$plotheight, units = "cm", dpi = 600) } zip(zipfile = file, files = fs) } )
由于 downloadHandler
是下载你指定的对象,所以如果不设置 contentType
,shiny程序会更具对象的拓展名来确定数据类型,这样通过压缩多张图片的方式,绕过了无法用 downloadHandler
来循环下载多张图片的问题
如果很N张图片需要下载,而且速度比较慢的话,可以考虑用Shiny的Progress indicators,参考之前的Shiny用法整理(一),然后对上面代码修改下(指定个progress,然后设置每出一张图,进度条就增加1/N,并给出提示信息~):
output$download_plot <- downloadHandler( filename = function(){ paste0("plots", ".zip") }, # contentType = "image/png", content = function(file){ fs <- c() tmpdir <- tempdir() setwd(tempdir()) progress <- shiny::Progress$new() on.exit(progress$close()) progress$set(message = "Begin to download boxplots:", value = 0) for(i in 1:length(var_name)) { filelist <- paste0(var_name[i], ".png") g <- p[[i]] fs <- c(fs, filelist) ggsave(filename = filelist, plot = g, device = "png", width = 16, height = input$plotheight, units = "cm", dpi = 600) progress$inc(1/length(var_name), detail = "Please wait...") } zip(zipfile = file, files = fs) } )
但是对于这个进度条的位置不太满意(默认是右下角),如果下个对这个进度条进行修改,则需要重新设置 .shiny-notification
,这个是notification的类,至于如何查到shiny的notification相关类有哪些,则可以查看shiny的CSS代码 https://github.com/rstudio/shiny/blob/master/inst/www/shared/shiny.css
,搜索下shiny-notification即可,其默认的CSS如下:
.shiny-notification { background-color: #e8e8e8; color: #333; border: 1px solid #ccc; border-radius: 3px; opacity: 0.85; padding: 10px 8px 10px 10px; margin: 2px; }
Adjust size of Shiny progress bar and center it
,主要是修改notification的位置(当然也可以设置宽度和高度等等),如下:tags$head( tags$style( HTML(".shiny-notification { position:fixed; top: calc(50% + 250px);; left: calc(50% + 500px);; }" ) ) )
至于为什么是修改notification,是因为进度条的style选的就是notification,因此上述用法在 showNotification
中也是通用的
Shiny App Usage Tracking
对于如何监控你的shiny app,shiny官方给出了一整套完整的方法,如果你是用shinyapps.io、RStudio Connect以及Shiny Server Pro,那么无需考虑这个,如果是使用free shiny,则需要借助第三方工具Google Analytics / Piwik,可参考官方文档 Shiny App Usage Tracking
出于在墙内的原因,Google Analytics工具我是无法使用的,而Piwik是基于PHP+Mysql的,由于其开源又功能的强大,所以想立马使用不太现实,所以我想寻找一种基于shiny或者R就能使用的简单监控系统,因为我只需要知道访问量和点击量就行
我先找到一个作者使用其自己的写的R代码来监听他在服务器上运行的所有shiny程序,其实是R代码来调用netstat命令来
实现的,这样可以简单统计用户访问量了,参考文章 How to monitor app usage on Shiny Server Open Source
但是这个方法并不能很好的解决我的需求,因此我还找了另一个作者提供的方法,使用shiny的一些插件来获取网页用户填写的信息,参考文章 Mimicking a Google Form with a Shiny app
按照作者的意思,其是mimicks a Google Form,将用户填写的提交的信息收集并存储起来,然后再可视化用于展示用户信息,那么在UI中只需要增加几个框用于用户填写信息
fluidRow( column( 3, selectInput("usertype", h4("User Type", span("*", class = "mandatory_star")), choices = list("技术支持", "学术顾问", "其他")) ), column( 3, textInput("userid", h4("User Name", span("*", class = "mandatory_star")), placeholder = "...") ), column( 3, textInput("projectid", h4("Project Id", span("*", class = "mandatory_star")), placeholder = "For example P20180100001") ) )
然后再server中将填写的信息记录下来(包括日期等信息),然后存储到指定文件中
log_con <- data.frame("boxplot_count", input$usertype, input$userid, input$projectid, format(Sys.time(), "%Y-%m-%d-%H-%M")) write.table(log_con, file = "log/tools.log", sep = "\t", row.names = F, col.names = F, quote = F, append = T)
关于shiny存储数据可以查看其官方文档 Persistent data storage in Shiny apps ,包括如果调用各个类型数据库等,我这只是简单使用Local storage
那么如何统计点击量呢,如果是一般按钮的点击,可以粗暴点用shiny基本用法中的,点击一次就计数一次,但是当我的情况是需要统计图片超链接的点击量,那么上述方法就不可行了
这是得借助shinyJS这个JS包来实现,其实这个需求对于正常的前端IT来说,就是一个JS命令的问题,那么用shinyJS则要其 onclick
函数来实现,现在在UI中设定好图片超链接的id,也就是类
div( tags$a(id = "count_id", tags$img(src="plot.png", width = "100%"), href = "http://xxx:3838/plot/"), tags$h3("Plot Tools", style = "color:#47a3da; font-family: sans-serif"), )
然后再server中对于这个ID使用onclick事件,并记录点击相关信息
shinyjs::onclick(id = "count_id", { log_con <- data.frame("boxplot_count", input$usertype, input$userid, input$projectid, format(Sys.time(), "%Y-%m-%d-%H-%M")) write.table(log_con, file = "log/tools.log", sep = "\t", row.names = F, col.names = F, quote = F, append = T) })
这样结合上述,就能简单的实现用户的登录的记录以及超链接点击的记录等需求
本文出自于 http://www.bioinfo-scrounger.com 转载请注明出处
以上所述就是小编给大家介绍的《shiny用法整理(三)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- shiny用法整理(二)
- Shiny用法整理(一)
- Pandas数据可视化工具——Seaborn用法整理
- 照片整理系列二 —— 照片整理及归档的辛酸历程
- 我自己整理的码农周刊一周分享整理
- 【复习资料】ES6/ES7/ES8/ES9资料整理(个人整理)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。