内容简介:继续整理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资料整理(个人整理)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Machine Learning
Kevin Murphy / The MIT Press / 2012-9-18 / USD 90.00
Today's Web-enabled deluge of electronic data calls for automated methods of data analysis. Machine learning provides these, developing methods that can automatically detect patterns in data and then ......一起来看看 《Machine Learning》 这本书的介绍吧!