Reputation: 15
I am trying to change the values in 2 ValueBoxes (mean values of attribute 'pf_score' and 'ef_score' every year) with the help of slider, which has years 2008-2016. The output is visible as I wanted, but I am also seeing an error "object of type 'closure' is not subsettable"
UPDATE: I am not able to run entire code by clicking on Run-App. I am getting an error "Could not find function df1". I have to read all data frames first separately and then click Run-App to see the UI.
require(shiny)
require(dplyr)
require(shinydashboard)
shinyServer(function(input,output){
df <- read.csv("hfi_cc_2018.csv", header = T)
summary(df)
sapply(df, function(x) sum(is.na(x)))
#Replace Null Values
df[is.na(df)] <- 0
df[,5:ncol(df)] <- round(df[,5:ncol(df)], 2)
#adding selective columns new df1
#https://stackoverflow.com/questions/10085806/extracting-specific-columns-from-a-data-frame
df1<- df[, (names(df) %in% c("year","pf_score", "ef_score"
))]
output$select_years <- renderUI(
{
card <- df1 %>%
filter(year == input$years)
output$pfrank = renderValueBox(
valueBox(round(mean(card$pf_score),1),
"Personal Freedom Score")
)
output$efrank = renderValueBox(
valueBox(round(mean(card$ef_score),1),
"Economic Freedom Score")
)
}
)
})
require(shiny)
require(shinydashboard)
shinyUI(
dashboardPage(
dashboardHeader(title = "Human Freedom Index", titleWidth = 300),
dashboardSidebar(
sliderInput("years","Select Year:",
min = min(df1$year),
max = max(df1$year),
value = min(df1$year),
step = 1),
selectInput("variable","Select Freedom Factor:",
choices = colnames(df1)
)
),
dashboardBody(
uiOutput("select_years"),
fluidRow(
valueBoxOutput("pfrank"),
valueBoxOutput("efrank")
)
)
)
)
Upvotes: 0
Views: 2265
Reputation: 365
This type of error is discussed in: Error in <my code> : object of type 'closure' is not subsettable
In this case, it looks like you have card
as a plain data frame whereas you need a reactive
so that it gets recalculated as you move the slider. Also, the expression for renderUI
can be simplified to just a list. e.g.,
ui <- shinyUI( ... )
server <- function(input, output) {
card <- reactive({
df1 %>%
filter(year == input$years)
})
output$select_years <- renderUI(
c(renderValueBox(valueBox(round(mean(card()$pf_score), 1),
"Personal Freedom Score")),
renderValueBox(valueBox(round(mean(card()$ef_score), 1),
"Economic Freedom Score"))))
}
shinyApp(ui, server)
Also note that the new version of Shiny simplifies the syntax a bit. The code can just go in app.R
and you need to define ui
and server
.
Upvotes: 1
Reputation: 2022
You could use an observe()
to render the value boxes instead of renderUI
:
require(shiny)
require(dplyr)
require(shinydashboard)
df <- read.csv("hfi_cc_2018.csv", header = T)
summary(df)
sapply(df, function(x) sum(is.na(x)))
#Replace Null Values
df[is.na(df)] <- 0
df[,5:ncol(df)] <- round(df[,5:ncol(df)], 2)
#adding selective columns new df1
#https://stackoverflow.com/questions/10085806/extracting-specific-columns-from-a-data-frame
df1 <- df[, (names(df) %in% c("year","pf_score", "ef_score"))]
#UI
ui <- dashboardPage(
dashboardHeader(title = "Human Freedom Index", titleWidth = 300),
dashboardSidebar(
sliderInput("years","Select Year:",
min = min(df1$year),
max = max(df1$year),
value = min(df1$year),
step = 1),
selectInput("variable","Select Freedom Factor:",
choices = colnames(df1)
)
),
dashboardBody(
fluidRow(
valueBoxOutput("pfrank"),
valueBoxOutput("efrank")
)
)
)
#Server
server <- function(input,output){
observe({
card <- df1 %>%
filter(year == input$years)
output$pfrank = renderValueBox(
valueBox(round(mean(card$pf_score),1),
"Personal Freedom Score")
)
output$efrank = renderValueBox(
valueBox(round(mean(card$ef_score),1),
"Economic Freedom Score")
)
})
}
#Run app
shinyApp(ui, server)
Upvotes: 0