I have an R script (let us call it myscript.R) which is a function of input$year.
Once I select the year in the shinyapp I want that the computer run "myscript.R" ?
I tried kind of the following structure,but it does not work
fun=function(input,ouput,session){
year= input$year
}
observeEvent(input$year,{
fun(input,output,session)
})
Your answers are appreciated!
I am not sure if a function from a script is really what you want here. If you want to make output dependent on input, this is how you do it in Shiny:
library(shiny)
ui <- fluidPage(
selectInput("year","Year: ",choices=c(2000,2001,2002)),
textOutput("test")
)
server <- function(input, output, session) {
test_reactive <- reactive({
year = as.numeric(input$year)
year = year + 1
return(year)
})
output$test <- renderText({
test_reactive()
})
}
runApp(shinyApp(ui, server))
If you really want to call a function from a script, and within script.R you have a function, like:
my_function <- function(year)
{
...
}
You should do source(script.R) somewhere above the server function, and do my_function(year) where I have added 1 to the year.
Hope this helps.
Related
I would like to create a loop that generates as many outputs as the user chooses.
for example, if the user chooses 10 models, 10 outputs of those 10 models will come out.
Note: I know that inputs cannot be used within the UI. I just use it as a reference to make it clearer to understand what I am trying to do.
Here is what I've tried:
shinyApp(ui= fluidPage(checkboxGroupInput('aa','model',c('a','b','c'), 'a'),
for(i in 1:length(input$aa)){
function(i){uiOutput(paste0('prob', i))}
}),
server = function(input, output){
for(i in input$aa){
assign(paste('output$prob',i,sep = ''),renderUI({paste('model',i)}))
}
})
Thanks.
In shiny, for loops don't work well, it's better to use lapply. Below you find a solution with lapply, you could also take a look at insertUI/removeUI
library(shiny)
ui <- fluidPage(checkboxGroupInput('aa','model',c('a','b','c'), 'a'),
uiOutput("formulas")
)
server <- function(input, output, session) {
output$formulas <- renderUI({
lapply(input$aa, function(model) {
verbatimTextOutput(paste0("prob_", model))
})
})
observeEvent(input$aa, {
lapply(input$aa, function(model) {
output[[paste0("prob_", model)]] <- renderPrint({paste0("model ", model)})
})
})
}
shinyApp(ui, server)
I'm new to Shiny and have hit a problem I can't find an answer for. Basically, I have a Shiny app that does some long calculations in a loop and I want it to output a "progress report" every few iterations. However, even though I reassign my reactive variable within the loop, the output doesn't update until the loop (or entire function?) has finished.
Here is a simplified test case of what I mean:
library(shiny)
# Basic interface
ui <- fluidPage(
actionButton("run", "Run"),
textOutput("textbox")
)
# Basic server with loop
server <- function(input, output) {
textvals=reactiveValues(a=0)
observeEvent(input$run, {
for(i in 1:10){
textvals$a=i # Expect output to update here, but doesn't
Sys.sleep(0.1) # Slight pause so isn't instantaneous
}
})
output$textbox <- renderText({
textvals$a
})
}
# Run the application
shinyApp(ui = ui, server = server)
What I would expect is that the display would update 1, 2, 3, ... 10 as the loop executes. Instead, it just jumps straight from 0 to 10. How can I force an update partway through the loop?
Thank you.
With using invalidateLater you can get something closed to what you want. Not the shortest way to do it I think, but it may help you to find a better solution.
library(shiny)
# Basic interface
ui <- fluidPage(
actionButton("run", "Run"),
textOutput("textbox")
)
# Basic server with loop
server <- function(input, output, session) {
textvals <- reactiveVal(0)
active <- reactiveVal(FALSE)
output$textbox <- renderText({
textvals()
})
observe({
invalidateLater(1000, session)
isolate({
if (active()) {
textvals(textvals() + 1)
if (textvals() > 9) {
active(FALSE)
}
}
})
})
observeEvent(input$run, {
active(TRUE)
})
}
# Run the application
shinyApp(ui = ui, server = server)
By the way, reactive and for loops don't really get on well. This may help : https://gist.github.com/bborgesr/e1ce7305f914f9ca762c69509dda632e
I'm trying to make a simple financial calculator that is capable of converting currencies as well. I couldn't go on without quantmod, to download new information. But when I try to apply its functions in shiny, there's some problem that I couldn't make out.
library(shiny)
library(quantmod)
ui <- fluidPage(
sidebarPanel(
textInput("curr", "Currency"),
actionButton("go", "1 dollar equals to:")
),
mainPanel(
verbatimTextOutput("res")
)
)
server <- function(input, output, session) {
result <- reactiveValues(data = NULL)
observeEvent(input$go, {
getSymbols(input$curr)
result$data <- data.frame(`input$curr`)
wanted <- result$data[nrow(result$data), ncol(result$data)]
})
output$res <- renderText({
paste(wanted)
})
}
shinyApp(ui, server)
When I tried to do the same in other script, without the inputs of shiny, it worked pretty well.
When I used BRL=X as the input$curr, it should work as in the script shown below.
getSymbols("BRL=X")
data <- data.frame(`BRL=X`)
data[nrow(data),ncol(data)]
But the error message that appear says that object "input$curr" was not found.
I'm working with R in an environment that doesn't have a good date picker and I'm trying to pop up a date picker using R to fill in the gap.
Most R date pickers require UI libraries like GTK. Shiny's doesn't.
All I'd like to do is pop up a date picker, let the user choose the date and then end the shiny session and pass the date back to continue the R script.
Here's what I have so far, but no success. I'm trying to assign the date to a global variable x.
library("shiny")
## Only run examples in interactive R sessions
if (interactive()) {
ui <- fluidPage(
# Default value is the date in client's time zone
dateInput("date2", "Date:"),
verbatimTextOutput("date2")
)
shinyApp(ui, server = function(input, output) {
reactive(x <<- input$date2)
})
}
But the variable x doesn't show up in the global env.
The issue here is that you're never calling that reactive object. In server, you'd have to do something like:
shinyApp(ui, server = function(input, output) {
observeEvent(input$date2, {x <<- input$date2})
})
This way, a change in input$date2 will trigger the global assignment of x.
You could also do something like this, where you assign the value to the global env when the session ends.
library("shiny")
## Only run examples in interactive R sessions
ui <- fluidPage(
# Default value is the date in client's time zone
dateInput("date2", "Date:"),
verbatimTextOutput("date2")
)
shinyApp(ui, server = function(input, output, session) {
session$onSessionEnded(function() {
assign("x", isolate(dat()), pos = .GlobalEnv)
})
dat <- reactive({
req(input$date2);
x <- input$date2
x
})
})
I am writing a server script of shiny where I want reactive() to first check the data on my c drive, if it's there then well and good else do the other data processing and save it for the next iteration.
And the name of data is dependent on input$var
So that next time it will be really quick to create the charts
Following is just a running example of my big problem
library(shiny)
library(datasets)
library(ggplot2)
mt=mtcars
shinyServer(function(input, output) {
data1 =reactive({
if(file.exists("input$var.csv")
{data=read.csv(input$var.csv)})
else{
data=mt[mt$cyl==input$var,]
write.csv(data,file="c:\\input$var.csv")
}
})
output$Plot1 <- renderPlot({
data2=data1()
ggplot(data2$d,aes(x=gear,y=wt))+geom_boxplot() })
})
Use paste0 as timfaber said you. In R functions which deals with files you have to give a complete string then paste0 allows you to give a string like "name_with_what_is_in_input$var.csv".
ibrary(shiny)
library(datasets)
library(ggplot2)
mt=mtcars
shinyServer(function(input, output) {
data1 =reactive({
if(file.exists(paste0(input$var,".csv"))
{data=read.csv(paste0(input$var,".csv"))})
else{
data=mt[mt$cyl==input$var,]
write.csv(data,file=paste0("c:\\",input$var,".csv"))
}
})
output$Plot1 <- renderPlot({
data2=data1()
ggplot(data2$d,aes(x=gear,y=wt))+geom_boxplot() })
})