I am writing shiny apps that take an object (a photograph or a matrix of numbers mostly) and making a set of plots to explore the object. I want to setup the shiny app as a function so I can call it from a command line and pass the object of interest directly to it. I would like to be able to return the name of the object in titles of the graphs and so forth. I can do this with substitute() outside of the shiny app, but when I put it in the shiny app it returns the name of object "inside the scope" of the shiny function, not the name of the objet that was passed to the shiny function.
Per suggestion, I used styler to improve the style of the code:
#this puts Children in the title of the graph which is what I want but I want a shiny app:
myPlot <- function(x) {
plot(1:10, main = substitute(x))
}
children <- "10"
myPlot(children)
#when I do it inside the shiny App
#this puts x in the title of the plot which is not what I want:
require(shiny)
app1 <- function(x) {
shinyApp(
ui = mainPanel(plotOutput("plot1")),
server = function(input, output) {
output$plot1 <- renderPlot(myPlot(x))
}
)
}
app1(children)
before the styler package:
#this puts Children in the title of the graph which is what I want but I want a shiny app:
myPlot = function(x){
plot(1:10,main=substitute(x))
}
children = "10"
myPlot(children)
#when I do it inside the shiny App
#this puts x in the title of the plot which is not what I want:
app1 = function(x) {shinyApp(
ui = mainPanel(plotOutput("plot1")) ,
server = function(input,output){output$plot1 <- renderPlot( plot(1:10,main=substitute(x)) )}
)}
app1(children)
CodePudding user response:
You can do:
app1 = function(x) {
title <- substitute(x)
shinyApp(
ui = mainPanel(plotOutput("plot1")),
server = function(input, output){
output$plot1 <- renderPlot( plot(1:10, main = title) )
}
)
}
CodePudding user response:
The substitute
function is very useful but you have to be careful with it.
The second argument of substitute
is env
and could be appropriately updated so the function will work in any place.
fun <- function(x) substitute(expr = x, env = environment()) # current env is environment()
# you can control the scope of the substitute
# the parent.frame give us access to the nth previous env
fun_deep2 <- function(x) {
fun_temp <- function(x) {
substitute(expr = x, env = parent.frame(n = 1))
}
fun_temp(x)
}
fun(hey)
fun_deep2(hey)
Please try to style your code before sharing e.g. with styler
package.
On the other hand try to follow base programming rules like DRY, reuse and others. Taking it into account substitute
could be a wrong direction. Additional argument for a name could be a right one. Example why substitute which is used even by many base R stat functions is dangerous.
x = 1:10; y = 1:10; do.call(t.test, list(x = x, y = y))
or
do.call(t.test, list(x = 1:10, y = 1:10))
We get totally different names than we expected.
So any function which using substitute could not be used so easy in the automatic way, like by do.call
.