如何在Shiny应用的输出图表中显示传入对象的名称
问题描述
我正在编写一个可接收对象(主要是图片或数值矩阵)的Shiny应用,用于生成图表探索该对象。希望将Shiny应用封装为函数,支持从命令行调用并直接传入目标对象,同时在图表标题等处显示该对象的实际名称。
在Shiny应用外部,我可以用substitute()实现此功能,但将其放入Shiny应用后,返回的是Shiny函数内部作用域的参数名(如x),而非传入的实际对象名。以下是用styler优化前后的代码示例:
优化后代码
# 此代码能在图表标题显示Children,正是我想要的,但我需要在Shiny应用中实现: myPlot <- function(x) { plot(1:10, main = substitute(x)) } children <- "10" myPlot(children) # 在Shiny应用中执行时,图表标题显示的是x,不符合需求: require(shiny) app1 <- function(x) { shinyApp( ui = mainPanel(plotOutput("plot1")), server = function(input, output) { output$plot1 <- renderPlot(myPlot(x)) } ) } app1(children)
优化前代码
# 此代码能在图表标题显示Children,正是我想要的,但我需要在Shiny应用中实现: myPlot = function(x){ plot(1:10,main=substitute(x)) } children = "10" myPlot(children) # 在Shiny应用中执行时,图表标题显示的是x,不符合需求: app1 = function(x) {shinyApp( ui = mainPanel(plotOutput("plot1")) , server = function(input,output){output$plot1 <- renderPlot( plot(1:10,main=substitute(x)) )} )} app1(children)
解决方案
问题出在Shiny的server函数是闭包,它访问的x是app1函数的参数,在server内部调用substitute(x)只会得到参数名x,而非传入的实际对象名。
解决思路是在app1函数的顶层先捕获传入对象的名称,再传递给server中的绘图逻辑:
require(shiny) myPlot <- function(x, obj_name) { plot(1:10, main = obj_name) } app1 <- function(x) { # 在app1顶层捕获实际对象名称 obj_name <- deparse(substitute(x)) shinyApp( ui = mainPanel(plotOutput("plot1")), server = function(input, output) { output$plot1 <- renderPlot(myPlot(x, obj_name)) } ) } children <- "10" app1(children)
也可以直接在app1内部处理绘图,无需单独的myPlot函数:
require(shiny) app1 <- function(x) { obj_name <- deparse(substitute(x)) shinyApp( ui = mainPanel(plotOutput("plot1")), server = function(input, output) { output$plot1 <- renderPlot(plot(1:10, main = obj_name)) } ) } children <- "10" app1(children)
核心是用deparse(substitute(x))在**外部作用域(app1函数顶层)**捕获传入对象的字符串名称,再让server闭包引用这个预存的名称,而非在server内部调用substitute。
内容的提问来源于stack exchange,提问作者DashdotdotDashdotdot
相关产品推荐
相关产品推荐

