Why am I getting Error on Shiny Host but not local - r

I have created a shinyapp, with tabs, that takes a dataframe and allows the user to filter it - then create a histogram based on the filters. This app works great when I run it on my local machine. However, When I publish it to shinyapps.io I get the following error:
ERROR: object of type 'closure' is not subsettable
I understand from other posts that the dataframe needs to be reactive or may need to be reactive? However when I enclose the data frame in reactive like so:
dat <- reactive(df)
I get the same error.
The files are located at github
or here:
library(shiny)
library(DT)
#server.R
shinyServer(function(input, output) {
df <- read.csv('orioles.csv')
output$table <- DT::renderDataTable(DT::datatable({
dat <- df
if (input$opp != "All") {
dat <- dat[dat$Opponent == input$opp,]
}
if (input$prk != "All") {
dat <- dat[dat$parkId == input$prk,]
}
if (input$strt != "All") {
dat <- dat[dat$Day.or.Night == input$strt,]
}
dat
}))
output$plot1 <- renderPlot({
dat <- df
if (input$opp != "All") {
dat <- dat[dat$Opponent == input$opp,]
}
if (input$prk != "All") {
dat <- dat[dat$parkId == input$prk,]
}
if (input$strt != "All") {
dat <- dat[dat$Day.or.Night == input$strt,]
}
hist(dat$BAL_SCORE, main = "Based on Filters", xlab = "Runs", ylab = "Frequency of runs scored", breaks = 20, col = "orange" )
})
})
UI:
library(shiny)
library(DT)
navbarPage(
title = 'Navigation',
tabPanel('Data Table', fluidPage(
titlePanel("Baltimore Orioles Game Results from 2010-2015"),
# Create a new Row in the UI for selectInputs
fluidRow(
column(4,
selectInput("opp",
"Opponent:",
c("All",
unique(as.character(df$Opponent))))
),
column(4,
selectInput("prk",
"Ball Park:",
c("All",
unique(as.character(df$parkId))))
),
column(4,
selectInput("strt",
"Day or Night Game:",
c("All",
unique(as.character(df$Day.or.Night))))
)
),
# Create a new row for the table.
fluidRow(
DT::dataTableOutput("table")
)
)),
tabPanel('Runs', fluidPage(
titlePanel("Runs Scored in filtered games"),
fluidRow(
column(6,
plotOutput("plot1", width = 800, height = 600)
)
)
))
)

I was able to get my App Working. The error was occuring because the data frame was not loading the way I had it set up. Solution is posted on github link shown above.

You'll get a more concise code using reactive and combining your subsetting conditions:
shinyServer(function(input, output) {
df <- read.csv('orioles.csv')
dat <- reactive(
df[(input$opp == "All" | df$Opponent == input$opp) &
(input$prk != "All" | df$parkId == input$prk) &
(input$strt != "All"| df$Day.or.Night == input$strt),])
output$table <- DT::renderDataTable(DT::datatable(dat()))
output$plot1 <- renderPlot({
hist(dat()$BAL_SCORE, main = "Based on Filters", xlab = "Runs",
ylab = "Frequency of runs scored", breaks = 20, col = "orange" )
})
})

Related

R Shiny: Set default value for reactive filter

I set up a filter by year using year_filter and would like the default view to be 2021. How to do I this given the code below? Currently, the default display is to show all data entries for all years.
The complete code and file can be found here for reference: https://drive.google.com/drive/folders/1C7SWkl8zyGXLGEQIiBEg4UsNQ5GDaKoa?usp=sharing
Thank you for your assistance!
# Define UI for application
ui <- fluidPage(
tags$div(
style = "padding: 10px;",
# Application title
titlePanel("Testing and Quarantine Measures"),
fluidRow(
uiOutput("CountryFilter_ui"),
uiOutput("YearFilter_ui")
),
fluidRow(
tags$div(style = "width: 100%; overflow: scroll; font-size:80%;",
DT::dataTableOutput('travel_table')
)
)
)
)
server <- function(input, output) {
# Render UI
output$CountryFilter_ui <- renderUI({
countries <- travel_clean %>%
pull(country_area)
selectInput('country_filter', 'Member State Filter', choices = countries, multiple = TRUE)
})
output$YearFilter_ui <- renderUI({
year <- travel_clean %>%
pull(year)
selectInput('year_filter', 'Year Filter', choices = year, multiple = TRUE)
})
# Filter data
travel_filtered <- reactive({
tmp_travel <- travel_measures %>%
select(-Sources)
if(is.null(input$country_filter) == FALSE) {
tmp_travel <- tmp_travel %>%
filter(`Country/area` %in% input$country_filter)
}
return(tmp_travel)
})
travel_filtered <- reactive({
tmp_travel <- travel_measures %>%
select(-Sources)
if(is.null(input$year_filter) == FALSE) {
tmp_travel <- tmp_travel %>%
filter(`Year` %in% input$year_filter)
}
return(tmp_travel)
})

Button to add entry column to r shiny datatable

I am looking to find a way to add a button to a datatable in r shiny that:
Adds an empty column to the data table each time it is clicked (and dataframe that made the table in the first place
Which the user can fill himself
With numeric or text values
And set their own column name to describe the type of entry values.
To for instance add lab note records to instrument data that is already in the shiny app manually
I am asking in case a more skilled person who has a better clue than me knows how to do this.
I have read a bunch of pages, but at best the example I found provides 1 fixed empty column with a fixed name
empty column
A dummy table from the package :
library(DT)
ui <- basicPage(
h2("The mtcars data"),
DT::dataTableOutput("mytable")
)
server <- function(input, output) {
output$mytable = DT::renderDataTable({
mtcars
})
}
shinyApp(ui, server)
You can use a button to add a new column to a R shiny datatable like this:
ui <- fluidPage(
h2("The mtcars data"),
DT::dataTableOutput("mytable"),
textInput('NewCol', 'Enter new column name'),
radioButtons("type", "Column type:",
c("Integer" = "integer",
"Floating point" = "numeric",
"Text" = "character")),
actionButton("goButton", "Update Table")
)
server <- function(input, output) {
mydata <- mtcars
output$mytable = DT::renderDataTable(df())
df <- eventReactive(input$goButton, {
if(input$NewCol!="" && !is.null(input$NewCol) && input$goButton>0){
if (input$type == "integer") v1 <- integer(NROW(mydata))
if (input$type == "numeric") v1 <- numeric(NROW(mydata))
if (input$type == "character") v1 <- character(NROW(mydata))
newcol <- data.frame(v1)
names(newcol) <- input$NewCol
mydata <<- cbind(mydata, newcol)
}
mydata
}, ignoreNULL = FALSE)
}
shinyApp(ui,server)
If you also need to edit the contents of the cells interactively, you can use renderRHandsontable instead of renderDataTable. Like this:
library(rhandsontable)
ui <- fluidPage(
h2("The mtcars data"),
rHandsontableOutput("mytable"),
textInput('NewCol', 'Enter new column name'),
radioButtons("type", "Column type:",
c("Integer" = "integer",
"Floating point" = "numeric",
"Text" = "character")),
actionButton("goButton", "Update Table")
)
server <- function(input, output) {
mydata <- mtcars[1:5,]
output$mytable = renderRHandsontable(df())
df <- eventReactive(input$goButton, {
if(input$NewCol!="" && !is.null(input$NewCol) && input$goButton>0){
if (input$type == "integer") v1 <- integer(NROW(mydata))
if (input$type == "numeric") v1 <- numeric(NROW(mydata))
if (input$type == "character") v1 <- character(NROW(mydata))
newcol <- data.frame(v1)
names(newcol) <- input$NewCol
mydata <<- cbind(mydata, newcol)
}
rhandsontable(mydata, stretchH = "all")
}, ignoreNULL = FALSE)
observe(if (!is.null(input$mytable)) mydata <<- hot_to_r(input$mytable))
}
shinyApp(ui,server)

Using a selected row to subset another table in r shiny

I am new to using DT in R shiny.Basically what i am trying to do here is to use the select value from the first table to filter the second table.
my Ui.r is
library(shiny)
library(shinydashboard)
ui <- dashboardPage(skin="green",
dashboardHeader(title="Inventory Management"),
dashboardSidebar(disable = TRUE),
dashboardBody(fluidRow(column(4,box(status="success",
uiOutput("Firstselection"),
br(),
uiOutput("Secondselection"))
),
column(4,infoBoxOutput("salesbox")),
column(4,infoBoxOutput("Runoutbox")),
column(4,infoBoxOutput("Excessbox"))),
actionButton("actionbtn","Run"),
fluidRow(tabBox(tabPanel(
DT::dataTableOutput(outputId="table"),title = "Stock Available for the category chosen",width = 12),
tabPanel(DT::dataTableOutput(outputId="asso"),title = "Associated products",width = 12)))
))
and my server is
server <-function(input, output, session) {
observeEvent(input$actionbtn, {source('global.r',local = TRUE)
#choose sub category based on category
output$Firstselection<-renderUI({selectInput("ray",
"Category:",
c("All",unique(as.character(bestpred$lib_ray))))})
output$Secondselection<-renderUI({selectInput("sray",
"Sub Category:",
c("All",unique(as.character(bestpred[bestpred$lib_ray==input$ray,"lib_sray"]))))})
# Filter data based on selections
output$table <- DT::renderDataTable({
data <- bestpred
if (input$ray != "All"){
data <- data[data$lib_ray == input$ray,]
}
if (input$sray != "All"){
data <- data[data$lib_sray == input$sray,]
}
data
},filter="top"
)
output$salesbox<-renderInfoBox({infoBox("Total Sales",sum(data()$Total_Sales),icon = icon("line-chart"))})
output$Runoutbox<-renderInfoBox({infoBox("Total Runout",sum(data()$status=="Runout"),icon = icon("battery-quarter"))})
output$Excessbox<-renderInfoBox({infoBox("Total excess",sum(data()$status=="Excess"),icon = icon("exclamation-triangle"))})
output$asso <- DT::renderDataTable({
asso <- test1
s=data[input$tablatable_rows_selected,1]
asso <- asso[asso$num_art == s,]
asso
},filter="top")
})}
So when i select a row in the output table i wanna use that as an filter for my asso table
this code dosent poup any error but the output table asso is always empty
Find a generalized solution in the following:
Adapted from here: https://yihui.shinyapps.io/DT-rows/
library(shiny)
library(DT)
server <- shinyServer(function(input, output, session) {
output$x1 = DT::renderDataTable(cars, server = FALSE)
output$x2 = DT::renderDataTable({
sel <- input$x1_rows_selected
if(length(cars)){
cars[sel, ]
}
}, server = FALSE)
})
ui <- fluidPage(
fluidRow(
column(6, DT::dataTableOutput('x1')),
column(6, DT::dataTableOutput('x2'))
)
)
shinyApp(ui, server)

Shiny R: Modifying the variable class

I am trying to create a shiny-app that load data-set, present the variable list and their classes and allow the user to modify the class of a selected variable. All the functions in the following code are working except to the last function in the server- observeEvent which not working when trying to modify the variable class. Any suggestions?
Thank you in advance,
Rami
`
rm(list = ls())
library(shiny)
library(shinydashboard)
library(DT)
ui <- dashboardPage(
dashboardHeader(title = "Shiny Example"),
#--------------------------------------------------------------------
dashboardSidebar(
sidebarMenu(
menuItem("Data", tabName = "data", icon = icon("th"))
)
),
#--------------------------------------------------------------------
dashboardBody(
#--------------------------------------------------------------------
tabItem(tabName = "data",
fluidPage(
fluidRow(
box(
selectInput('dataset', 'Select Dataset', list(GermanCredit = "GermanCredit",
cars = "cars",
iris = "iris")),
title = "Datasets",width = 4, status = "primary",
checkboxInput("select_all", "Select All Variable", value = TRUE),
conditionalPanel(condition = "input.select_all == false",
uiOutput("show.var"))
),
box(
title = "Variable Summary", width = 4, status = "primary",
DT::dataTableOutput('summary.data')
),
box(
title = "Modify the Variable Class", width = 4, status = "primary",
radioButtons("choose_class", label = "Modify the Variable Class",
choices = list(Numeric = "numeric", Factor = "factor",
Character = "character"),
selected = "numeric"),
actionButton("var_modify", "Modify")
)
)
)
)
)
)
#--------------------------------------------------------------------
# Server Function
#--------------------------------------------------------------------
server <- function(input, output,session) {
#--------------------------------------------------------------------
# loading the data
get.df <- reactive({
if(input$dataset == "GermanCredit"){
data("GermanCredit")
GermanCredit
}else if(input$dataset == "cars"){
data(cars)
cars
}else if(input$dataset == "iris"){
data("iris")
iris
}
})
# Getting the list of variable from the loaded dataset
var_list <- reactive(names(get.df()))
# Choosing the variable - checkbox option
output$show.var <- renderUI({
checkboxGroupInput('show_var', 'Select Variables', var_list(), selected = var_list())
})
# Setting the data frame based on the variable selction
df <- reactive({
if(input$select_all){
df <- get.df()
} else if(!input$select_all){
df <- get.df()[, input$show_var, drop = FALSE]
}
return(df)
})
# create list of variables
col.name <- reactive({
d <- data.frame(names(df()), sapply(df(),class))
names(d) <- c("Name", "Class")
return(d)
})
# render the variable list into table
output$summary.data <- DT::renderDataTable(col.name(), server = FALSE, rownames = FALSE,
selection = list(selected = 1, mode = 'single'),
options = list(lengthMenu = c(5, 10, 15, 20), pageLength = 20, dom = 'p'))
# storing the selected variable from the variables list table
table.sel <- reactive({
df()[,which(colnames(df()) == col.name()[input$summary.data_rows_selected,1])]
})
# Trying to modify the variable class
observeEvent(input$var_modify,{
modify.row <- which(colnames(df()) == col.name()[input$summary.data_rows_selected,1])
if( input$choose_class == "numeric"){
df()[, modify.row] <- as.numeric(df()[, modify.row])
} else if( input$choose_class == "factor"){
df()[, modify.row] <- as.factor(df()[, modify.row])
} else if( input$choose_class == "character"){
df()[, modify.row] <- as.character(df()[, modify.row])
}
})
}
shinyApp(ui = ui, server = server)
`
I would use reactiveValues() instead.
library(shiny)
# Define UI for application that draws a histogram
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("classType", "Class Type:", c("as.numeric", "as.character"))
),
mainPanel(
textOutput("class")
)
)
))
server <- shinyServer(function(input, output) {
global <- reactiveValues(sample = 1:9)
observe({
global$sample <- get(input$classType)(global$sample)
})
output$class <- renderText({
print(class(global$sample))
})
})
shinyApp(ui = ui, server = server)
In case you are interested:
Concerning your attempt: reactive() is a function and you called the output of the function by df()[, modify.row]. So in your code you try to change the output of the function, but that does not change the output of futures calls of that function.
Maybe it is easier to see in a simplified version:
mean(1:3) <- 1
The code can not change the mean function to output 1 in future. So thats what reactiveValues() help with :). Hope that helps!

Shiny Data table display all data using filter

I can create a data table in shiny that shows data for any individual buffalo but I can't figure out how to display all buffalo data at the same time. Any help is appreciated.
Sample Data:
cleanbuffalo <- data.frame(name = c("queen","toni","pepper"),
longitude = c(31.8,32,33),
latitude = c(-24,-25,-26))
Shiny UI:
shinyUI(navbarPage("Buffalo Migration", id ="nav",
tabPanel("Data",
fluidRow(
column(3,
selectInput("allnamesbuffalo", "Buffalo", c("All Buffalo" = "all buffalo", vars))
)
),
hr(),
DT::dataTableOutput("buffalotable")
)
)
)
Shiny Server:
shinyServer(function(input, output, session) {
observe({
allnamesbuffalo <- if (is.null(input$allnamesbuffalo)) character(0) else {
filter(cleanbuffalo, name %in% input$allnamesbuffalo) %>%
`$`('name') %>%
unique() %>%
sort()
}
})
output$buffalotable <- DT::renderDataTable({
df <- cleanbuffalo %>%
filter(
cleanbuffalo$name == input$allnamesbuffalo,
is.null(input$allnamesbuffalo) | name %in% cleanbuffalo$name
)
action <- DT::dataTableAjax(session,df)
DT::datatable(df, options = list(ajax = list(url = action)),
escape = FALSE)
})
})
Here is a working example. Note that I added stringsAsFactors=F in your data frame, otherwise you need to use levels(cleanbuffalo$name) to get the names.
library(shiny)
library(dplyr)
cleanbuffalo <- data.frame(name = c("queen","toni","pepper"),
longitude = c(31.8,32,33),
latitude = c(-24,-25,-26), stringsAsFactors = F)
ui <- shinyUI(fluidPage(
titlePanel("Example"),
sidebarLayout(
sidebarPanel(
selectInput("allnamesbuffalo", "Buffalo", c("all", cleanbuffalo$name))
),
mainPanel(
dataTableOutput("buffalotable")
)
)
))
server <- shinyServer(function(input, output, session) {
output$buffalotable <- renderDataTable({
names <- NULL
if (input$allnamesbuffalo == "all") {
names <- cleanbuffalo$name
} else {
names <- input$allnamesbuffalo
}
filter(cleanbuffalo, name %in% names)
})
})
shinyApp(ui = ui, server = server)

Resources