I am trying to append the user input to the output table in Shiny app. And when the user changes any values for Total Cost it should update in the table before I click on run. How can I fix that?
library(dplyr)
library(shiny)
shinyApp(
ui = basicPage(
mainPanel(
numericInput("model_input", label = h5("Total Cost"), value = 10000),
numericInput("iterations", label = h5("Runs"), value = 900),
actionButton("run", "Run"),
actionButton("reset", "reset"),
tableOutput("view")
)
),
server = function(input, output) {
v <- reactiveValues(data = mtcars %>% mutate(budget = input$model_input)) # this makes sure that on load, your default data will show up
observeEvent(input$run, {
v$data <- mtcars %>% mutate(new = mpg * input$model_input +input$iterations)
})
observeEvent(input$reset, {
v$data <- mtcars # your default data
})
output$view <- renderTable({
v$data
})
}
)
You cant use input$model_input outside a reactive context. That was probably causing some issues. We simple move it outside into an observeEvent.
library(dplyr)
library(shiny)
shinyApp(
ui = basicPage(
mainPanel(
numericInput("model_input", label = h5("Total Cost"), value = 10000),
numericInput("iterations", label = h5("Runs"), value = 900),
actionButton("run", "Run"),
actionButton("reset", "reset"),
tableOutput("view")
)
),
server = function(input, output) {
v <- reactiveValues(data = mtcars) # this makes sure that on load, your default data will show up
observeEvent(input$model_input,{
v$data <- v$data %>% mutate(budget = input$model_input)
})
observeEvent(input$run, {
v$data <- mtcars %>% mutate(new = mpg * input$model_input +input$iterations)
})
observeEvent(input$reset, {
v$data <- mtcars # your default data
})
output$view <- renderTable({
v$data
})
}
)
Related
I am using the mtcars dataset and have created another column that is a random number(x) * 2. I have then used the renderDataTable in r shiny to print it. I now want to use renderPlot({}) on the new_col column and any other column. How would I go about calling that new column?
library(shiny)
library(ggplot2)
df<- mtcars
ui<- fluidPage(
titlePanel("Mtcars"),
sidebarLayout(
sidebarPanel(
selectInput(inputID = 'test', label = "TEST", choices = c(1,2,3,4), selected = 3)
mainPanel(
DT::dataTableOutput('table1')
plotOutput('basicplot')
))
server <- function(input, output) {
func<-function(x){
df%>%
mutate(new_col = x*2)
output$table1 <- renderTable({
func(2)
})
output$basicplot <-renderPlot({
plot(* $new_col, *$mpg) #what do i call the new dataframe with the new_col
})
)
shinyApp(ui = ui, server = server)
You had numerous syntax errors. Please check it before posting a question in the future. Try this
library(shiny)
library(ggplot2)
df<- mtcars
ui<- fluidPage(
titlePanel("Mtcars"),
sidebarLayout(
sidebarPanel(
selectInput('test', label = "TEST", choices = names(df)[-1] )
),
mainPanel(
DTOutput('table1'),
plotOutput('basicplot')
)
)
)
server <- function(input, output) {
mydata <- reactive({
df %>%
mutate(new_col = as.numeric(df[[input$test]])*2)
})
output$table1 <- renderDT({
mydata()
})
output$basicplot <-renderPlot({
req(mydata())
df <- data.frame(mydata()$new_col,mydata()$mpg)
plot(df)
})
}
shinyApp(ui = ui, server = server)
I want to select a variable from the data and show the correlation between the selected variable and the variable that selected before. Happiness is my data and score is my selected variable that I choose. I have an error "invalid argument type" Thank you.
shinyApp(
ui = fluidPage(
titlePanel(),
varSelectInput("variable", "Variable:", happiness),
mainPanel(
p(),
p(),
fluidRow(
column(6,plotOutput(outputId="plotgraph1", width="300px",height="300px")),
column(6,plotOutput(outputId="plotgraph2", width="300px",height="300px")),
column(6,tableOutput(outputId="correl.out"))
)
)
),
server = function(input, output) {
output$plotgraph1 <- renderPlot({
ggplot(happiness, aes(x=!!input$variable,y=Score)) + geom_smooth()
})
output$plotgraph2 <- renderPlot({
ggplot(happiness, aes(x=!!input$variable)) + geom_histogram()
})
output$correl.out <- renderTable({
cor(x=!!input$variable,y=happiness$Score)
})
}
)
# We want to use multiple variables to select.
if (FALSE) {
shinyApp(
ui = fluidPage(
varSelectInput("variables", "Variable:", happiness, multiple = TRUE),
tableOutput("data")
),
server = function(input, output) {
output$data <- renderTable({
if (length(input$variables) == 0) return(happiness)
happiness %>% dplyr::select(!!!input$variables)
}, rownames = TRUE)
}
)}
}
)
If I add a debounce to a get_data() reactive expression, the first time the data is retrieved the plot does not render. However, changing the data (by selecting a new mpg) causes the plot to then render. Why is this? Is there a workaround?
Here is a simple minimal example demonstrating the problem. Try removing %>% debounce(500) to see that it works as expected without it:
if (interactive()) {
options(device.ask.default = FALSE)
library(shiny)
library(magrittr)
ui <- fluidPage(
selectInput("select", label = "select mpg", choices = c(mtcars$mpg, ""), selected = ""),
plotOutput("plot")
)
server <- function(input, output, session) {
get_data <- reactive({
req(input$select)
mtcars[mtcars$mpg == input$select,]
}) %>% debounce(500)
get_plot <- reactive({
data <- get_data()
print(data)
plot(get_data())
})
output$plot <- renderPlot({
get_plot()
})
}
shinyApp(ui, server)
}
Couple of things going on here. I don't think we are allowed to have duplicates in a select input. mtcars$mpg has duplicate values inside it. Setting the initial value to "" is also causing strange behaviors. If you really want the initial plot to be empty along with debounce we could set it to " ". Here is what that would look like.
if (interactive()) {
options(device.ask.default = FALSE)
library(shiny)
library(magrittr)
ui <- fluidPage(
selectInput("select", label = "select mpg", choices = c(" ",unique(mtcars$mpg)),selected = " "),
plotOutput("plot")
)
server <- function(input, output, session) {
get_data <- reactive({
req(input$select)
if(!is.na(as.numeric(input$select))) mtcars[mtcars$mpg == input$select,] else NULL
}) %>% debounce(500)
get_plot <- reactive({
req(get_data())
data <- get_data()
print(data)
plot(get_data())
})
output$plot <- renderPlot({
get_plot()
})
}
shinyApp(ui, server)
}
Else if you're okay with having an initial plot the following works. Note its important to use unique()
if (interactive()) {
options(device.ask.default = FALSE)
library(shiny)
library(magrittr)
ui <- fluidPage(
selectInput("select", label = "select mpg", unique(mtcars$mpg)),
plotOutput("plot")
)
server <- function(input, output, session) {
get_data <- reactive({
req(input$select)
mtcars[mtcars$mpg == input$select,]
}) %>% debounce(500)
get_plot <- reactive({
req(get_data())
data <- get_data()
print(data)
plot(get_data())
})
output$plot <- renderPlot({
get_plot()
})
}
shinyApp(ui, server)
}
I even tried replacing the select input with selectizeInput("select", label = "select mpg", choices = unique(mtcars$mpg),multiple = TRUE,options = list(maxItems = 1)) This still caused issues.
I would like to prepare a Shiny App in which the user can fill one column (e.g. Col1) with numbers and then press a button to generate entries for Col2 (a transformation of values introduced to Col1, e.g. multiply each row of Col1 by a random number).
How should I add the button to the following sample code:
library(rhandsontable)
library(shiny)
# add a sparkline chart
DF$chart = sapply(1:10, function(x) jsonlite::toJSON(list(values=rnorm(10))))
rhandsontable(DF, rowHeaders = NULL) %>%
hot_col("chart", renderer = htmlwidgets::JS("renderSparkline"))
editTable <- function(DF, outdir=getwd(), outfilename="table"){
ui <- shinyUI(fluidPage(
titlePanel("Edit and save a table"),
sidebarLayout(
sidebarPanel(
helpText("Shiny app based on an example given in the rhandsontable package.",
"Right-click on the table to delete/insert rows.",
"Double-click on a cell to edit"),
wellPanel(
h3("Table options"),
radioButtons("useType", "Use Data Types", c("TRUE", "FALSE"))
),
br(),
wellPanel(
h3("Save"),
actionButton("save", "Save table")
),
wellPanel(
textOutput('result')
)
),
mainPanel(
rHandsontableOutput("hot")
)
)
))
server <- shinyServer(function(input, output) {
values <- reactiveValues()
## Handsontable
observe({
if (!is.null(input$hot)) {
DF = hot_to_r(input$hot)
} else {
if (is.null(values[["DF"]]))
DF <- DF
else
DF <- values[["DF"]]
}
values[["DF"]] <- DF
})
output$hot <- renderRHandsontable({
DF <- values[["DF"]]
if (!is.null(DF))
rhandsontable(DF, useTypes = as.logical(input$useType), stretchH = "all")
})
## Save
observeEvent(input$save, {
finalDF <- isolate(values[["DF"]])
saveRDS(finalDF, file=file.path(outdir, sprintf("%s.rds", outfilename)))
})
})
## run app
runApp(list(ui=ui, server=server))
function(input, output)
return(invisible())
}
( DF <- data.frame(Col1=1:10, Col2=runif(10), stringsAsFactors = FALSE))
editTable(DF)
Are you looking for something like that:
ui <- shinyUI(fluidPage(
titlePanel("Edit and save a table"),
sidebarLayout(
sidebarPanel(
helpText("Shiny app based on an example given in the rhandsontable package.",
"Right-click on the table to delete/insert rows.",
"Double-click on a cell to edit"),
wellPanel(
h3("Table options"),
radioButtons("useType", "Use Data Types", c("TRUE", "FALSE")),
actionButton("Calculate", "Calculate column 2")
),
br(),
wellPanel(
h3("Save"),
actionButton("save", "Save table")
),
wellPanel(
textOutput('result')
)
),
mainPanel(
rHandsontableOutput("hot")
)
)
))
server <- shinyServer(function(input, output) {
#extract data from the table to be used
portfoliovals2 <- reactive({
live_data = hot_to_r(input$hot)[,1]
return(live_data)
})
#extract data to be used
portfoliovalsB2 <- reactive({
live_data = hot_to_r(input$hot)[,2]
return(live_data)
})
## create a new df every time the table is modified
new_df_g <- reactive({
initial_dataEdit = portfoliovals2()
initial_dataEditB = portfoliovalsB2()
initial_dataEditW <- data.frame(initial_dataEdit, initial_dataEditB)
return(initial_dataEditW)
})
output$hot <- renderRHandsontable({
if (input$Calculate ==0){
initial_data = data.frame(Col1=1:10, Col2=runif(10), stringsAsFactors = FALSE)
} else {
initial_data = new_df_g()
initial_data <- plyr::rename(initial_data, c("initial_dataEdit"="Col1", "initial_dataEditB"="Col2"))
initial_data$Col2 <- initial_data$Col1 * 1.3
}
rhandsontable(initial_data, readOnly = FALSE, rowHeaders = NULL, height = 600) %>%
hot_cols(columnSorting = TRUE)
})
})
## Save
observeEvent(input$save, {
finalDF <- new_df_g()
saveRDS(finalDF, file=file.path(outdir, sprintf("%s.rds", outfilename)))
})
})
## run app
runApp(list(ui=ui, server=server))
I user renderTable to show some data. However, sometimes the data table is empty, in which case I'd like to print "No data to show" or something similar. the default by renderTable is to show nothing for empty data. can this be changed? how?
You can use a condition into a renderUi to render either a message or a "tableOutput" (you can't render directly the table)
datas <- data.frame()
shiny::runApp(list(
ui = pageWithSidebar(
headerPanel("Example"),
sidebarPanel(
selectInput("dataset", "Dataset", choices = c("iris", "datas"))
),
mainPanel(
uiOutput("ui")
)
),
server = function(input, output, session) {
datasetInput <- reactive({
switch(input$dataset,
"iris" = iris,
"datas" = datas)
})
output$ui <- renderUI({
if(nrow(datasetInput()) == 0)
return("No data to show")
tableOutput("table")
})
output$table <- renderTable({
head(datasetInput())
})
}
))
I think you are looking for something like validate function.
Using example code provided by Julien:
datas <- data.frame()
shiny::runApp(list(
ui = pageWithSidebar(
headerPanel("Example"),
sidebarPanel(
selectInput("dataset", "Dataset", choices = c("iris", "datas"))
),
mainPanel(
tableOutput('table')
)
),
server = function(input, output, session) {
datasetInput <- reactive({
switch(input$dataset,
"iris" = iris,
"datas" = datas)
})
output$table <- renderTable({
y <- head(datasetInput())
validate(
need(nrow(y) > 0, "No Data to show")
)
y
})
}
))
If you still want to show a "table" within the UI, do this:
output$table_output <- renderTable {
data <- data.frame(a = c(1,2),
b = c(8,9)) #example data.frame
if (nrow(data) > 0) {
data
} else {
datatable(data.frame(Nachricht = "Die ausgewählte Schnittstelle enthält hierfür keine Daten."))
}
}