I am still quite new to shiny and ggplot so I am not sure what is causing the problem and I have posted different problems with this code previously however I have come across a new issue... when I run the code my plot does not appear and instead I get an error: Warning: Error in FUN: object "total_pigs" not found.
I get this error regardless of the options I choose in the selectInput "x"function.
I have a separate CSV file within the same directory as the app.R file. The selectInput(s) matches the columns and rows within the CSV, I was hoping that my code would simply read the data stored within it and this will generate my plot points.
library(shiny)
library(ggplot2)
path <- file.path("eu_pigs.csv", stringsAsFactors = FALSE)
ui <- fluidPage(
titlePanel("Breeding Numbers 2016 - 2018 (pig)"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "x",
label = "Pig Breeds:",
choices = c("total_pigs", "female_breeding_herd",
"in_pig_sows", "in_pig_gifts", "other_sows",
"maiden_gilts", "boars_for_service", "other_pigs"),
selected = "total_pigs"),
selectInput(inputId = "y",
label = "Year by year change:",
choices = c(2016, 2017, 2018, sep = ""),
selected = 2016)
),
mainPanel(
plotOutput(outputId = "scatterplot")
)
)
)
server <- (function(input, output) {
output$scatterplot <- renderPlot({
ggplot(data = read.csv("eu_pigs.csv")) +
aes_string(x = input$x, y = input$y) +
geom_point()
})
})
shinyApp(ui, server)
I attach an image of my csv file.
As DS_UNI suggests, the issue probably lies with the structure of your data. ggplot2 wants to work with tidy data, so in this case that would mean each row represents a case, i.e. a year.
Here's what I think you need to do, although this is making some assumptions about what you want the end result to look like!
Step one: Read in the csv for data wrangling
pigs_data <- read.csv("eu_pigs.csv")
Step two: Make the first column into row names
row.names(pigs_data) <- pigs_data$pig_breeds
pigs_data[1] <- NULL
Step three: Transpose the data
pigs_data <- t(pigs_data)
You would then use pigs_data in your ggplot data argument.
Related
Currently creating a sales report generating site in R using Shiny. I have been struggling to pull the data from a CSV file the user imports into the dashboard itself. I need to use the data from my fileInput to run a calculation and then actively display these results in my shiny window. Ideally this would be initiated by the action of selecting the CSV file for the fileInput by the user and the calculations would occur.
Let's say this is the CSV that the user inputs
ID
DATE
GROSS
000001
5/22/22
75000
000002
5/25/22
100000
Here is an abridged version of the related code
# Load packages
library(shiny)
library(bslib)
library(shinyWidgets)
library(dplyr)
# Define static variables
mayquota <- 135000
# UI
ui <- navbarPage(title = "Example",
tabPanel(title = "Page 1",
fluidPage(inputPanel(textInput("key", "KEY")),
fixedRow(column(12, fileInput("salesdata", "SALES DATA",
width = 100%, buttonLabel = "SELECT"))),
inputPanel(currencyInput("profits", "PROFITS", format = "dollar",
value = 0, align = "right"),
currencyInput("quota", "QUOTA", format = "dollar",
value = 0, align = "right"),
currencyInput("difference", "DIFFERENCE",
format = "dollar", value = 0,
align = "right")))))
# Server
server <- function(input, output, session) {
prof <- reactive({read_csv(input$profits)})
toListen <- reactive({input$key})
observeEvent(toListen(),
{if(input$key == "test123")
{updateCurrencyInput(session, "quota", value = mayquota)
updateCurrencyInput(session, "difference", value = profits() - mayquota}})
}
# Run application
shinyApp(ui = ui, server = server)
I need to pull the sum of the GROSS column in the CSV and use it to updateCurrencyInput in the form of:
updateCurrencyInput(session, "profits", value = profits())
I was hoping that something like this would work:
toListenFile() <- reactive({input$salesdata})
observeEvent(toListenFile(), {profits <- reactive({prof() %>% summarize(sum(`GROSS`))})})
But I was given the error that summarize from dplyr could not be used on reactive data. So that is where I stand. Any help would be appreciated to achieve a similar function to dplyr in a reactive environment where the CSV data is inputted by the user.
It appears as though I have a solution to my issue, just wanted to share since I already opened the question.
server <- function(input, output, session) {
abcInput <- reactive({
req(input$salesdata)
tibble(read_csv(input$salesdata$datapath))
})
sumprof <- reactive({sum(abcInput()$`GROSS`)})
observeEvent(input$rdata, {updateCurrencyInput(session, "profits", value = sumprof())
})
There might be a more elegant way to achieve this, but this appears to work thus far.
I am trying to develop a Shiny app, a simple one. My intention at this point is to create a table and filter that table by various inputs.
Right now this is my code:
library("shiny")
library("gapminder")
library("ggplot2")
library("colourpicker")
library("plotly")
ui <- fluidPage(
h1("Demo"),
sliderInput(inputId = "valor", label = "Rango ",
min = min(data$value), max = max(data$value),
value = c(min(data$value), max(data$value))),
selectInput(inputId = "opc", label = "Measurements", choices = levels(data$measurement)),
tableOutput("table")
)
server <- function(input, output) {
output$table <- renderTable({
data <- data
data <- subset(
data,
value >= input$valor[1] & value <= input$valor[2]
)
data <- subset(
data,
measurement == input$opc
)
data
})
}
levels(data$measurement)
shinyApp(ui, server)
as you can see, very simple. However, this code returns the table empty and the selectInput with no options of selection. However, if I put the values of the column by hand, the code works fine!
selectInput(inputId = "opc", label = "Measurements", choices = c("heart_rate","oxygen_saturation")),
The code above works great, the table suddenly displays data again and it filters correctly. I just don't get it! The sliderInput works great as well. The data set has been included as an enviroment variable.
This are the two different outputs (first picture with written values, second picture using levels(data$measurement)):
Why is this happening to me?!
I am trying to get my head around RShiny by building what I thought would be a pretty simple but useful app. What I would like the app to do is allow the user to input some data made up of dates, numeric, and characters. Then when the user presses a save/submit button this data is appended onto a pre-existing data frame made up of previous recordings and over write the .csv of these recordings. I would also like this data to be presented to the users in the form of a table in the UI which is updated as soon as the user presses the save/submit button.
I have managed to get the majority of the UI features working, however, I am having real difficulty 1) saving the data in the correct format and 2) updating the table displayed on the UI. My current method of saving the data involves creating an isolated list of the input values and rbinding this to the original data frame. However, the formats of the input values appear to all revert to factors which is especially problematic with the date as the output is meaningless as far as I am aware. In terms of updating the UI I have attempted to create a reactive object out of the data frame and use this object as the data displayed in renderDataTable but this approach seems to have no affect.
I have created a dummy minimal example below.
Thank you for all your help in advance.
require(shiny)
require(tidyverse)
require(lubridate)
require(plotly)
#Would import the data in reality using read.csv() but to allow for an easily
#recreated example I made a dummy data frame
DateRecorded <- dmy(c("10/07/2018", "11/07/2018", "13/07/2018"))
Value <- c(1, 2, 3)
Person <- c("Bob", "Amy", "Charlotte")
df <- data.frame(DateRecorded, Value, Person)
ui <- fluidPage(
#UI Inputs
dateInput(inputId = "SessionDate", label = "Date Recorded", format = "dd-mm-yyyy"),
numericInput(inputId = "SessionValue", label = "Value Recorded", value = 0),
textInput(inputId = "SessionPerson", label = "Person Recording"),
actionButton(inputId = "Save", label = "Save"),
#UI Outputs
dataTableOutput("TheData"),
textOutput("TotRecorded")
)
# Define server logic required to draw a histogram
server <- function(input, output) {
#When "Save" is pressed should append data to df and export
observeEvent(input$Save, {
newLine <- isolate(c(input$SessionDate, input$SessionValue, input$SessionPerson))
isolate(df <- rbind(as.matrix(df), unlist(newLine)))
write.csv(df, "ExampleDataFrame.csv") #This export works but the date is saved incorrectly as "17729" not sure why
})
#Create a reactive dataset to allow for easy updating
ReactiveDf <- reactive({
df
})
#Create the table of all the data
output$TheData <- renderDataTable({
ReactiveDf()
})
#Create the totals print outs
output$TotRecorded <- renderPrint({
data <- ReactiveDf()
cat(nrow(data))
})
}
# Run the application
shinyApp(ui = ui, server = server)
I made some small tweaks.
You do not need isolate in the body of the observeEvent; it does not take a reactive dependency to values in its body.
I made ReactiveDf a reactiveVal instead of a reactive. This allows you to write its value from inside an observeEvent.
Instead of rowbinding a matrix and unlisting a list - the issue is that all the new values are parsed to the same class, while they are obviously not - it might be easier to rbind two data.frames, so create the newLine with newLine <- data.frame(DateRecorded = input$SessionDate, Value = input$SessionValue, Person = input$SessionPerson)
So a working example would be as shown below. Hope this helps!
require(shiny)
require(tidyverse)
require(lubridate)
require(plotly)
#Would import the data in reality using read.csv() but to allow for an easily
#recreated example I made a dummy data frame
DateRecorded <- dmy(c("10/07/2018", "11/07/2018", "13/07/2018"))
Value <- c(1, 2, 3)
Person <- c("Bob", "Amy", "Charlotte")
df <- data.frame(DateRecorded, Value, Person)
ui <- fluidPage(
#UI Inputs
dateInput(inputId = "SessionDate", label = "Date Recorded", format = "dd-mm-yyyy"),
numericInput(inputId = "SessionValue", label = "Value Recorded", value = 0),
textInput(inputId = "SessionPerson", label = "Person Recording"),
actionButton(inputId = "Save", label = "Save"),
#UI Outputs
dataTableOutput("TheData"),
textOutput("TotRecorded")
)
# Define server logic required to draw a histogram
server <- function(input, output) {
#When "Save" is pressed should append data to df and export
observeEvent(input$Save, {
newLine <- data.frame(DateRecorded = input$SessionDate, Value = input$SessionValue, Person = input$SessionPerson)
df <- rbind(df, newLine)
ReactiveDf(df) # set reactiveVal's value.
write.csv(df, "ExampleDataFrame.csv") #This export works but the date is saved incorrectly as "17729" not sure why
})
#Create a reactive dataset to allow for easy updating
ReactiveDf <- reactiveVal(df)
#Create the table of all the data
output$TheData <- renderDataTable({
ReactiveDf()
})
#Create the totals print outs
output$TotRecorded <- renderPrint({
data <- ReactiveDf()
cat(nrow(data))
})
}
# Run the application
shinyApp(ui = ui, server = server)
I have spent several hours trying to figure out how to generate a bar plot using ggplot2 for a shiny app I want to create. The ui works fine, however; the server function generates an empty plot.
The issue is with renderPlot function. I believe I must not be passing the reactive values properly to the aes_string arguments in ggplot.
C2 is a filtered dataset. The goal is to build a simple app in which the user selects a two variables, a dataset is filtered based upon those variables. The subsetted dataset is passed to ggplot data argument.
library(shiny)
library(dplyr)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput(inputId = "Demog",label = "Factor:",choices = c("HH Income" = "Income",
"Age Group" = "Age",
"US Region" = "Region") , selected = "Age"),
selectInput(inputId = "Car",label = "VW Model:",choices = c("BEETLE" = "BEETLE",
"CC" = "CC",
"EOS" = "EOS",
"GOLF" = "GOLF",
"GTI" ="GOLF SPORTSWAGEN GTI",
"JETTA" = "JETTA",
"PASSAT" = "PASSAT",
"TIGUAN" = "TIGUAN",
"TOUAREG" = "TOUAREG") , selected = "BEETLE"),
radioButtons(inputId = "Metric",label ="Measurement Type",choices =
c("Conquest Volume Index" = "TotCmpConqVol_IDX","C/D Ratio" = "TotCmpCDRatio_IDX"), selected = "TotCmpConqVol_IDX" )
)
),
mainPanel(
tags$h1("The Bar Charts"),
tags$h2("The metrics"),
plotOutput("P1")
)
)
server <- function(input, output){
library(ggplot2)
CONQDF <- read.csv("C:/Users/Reginald/Desktop/CONQ_VW/CONQUEST2.csv")
C2 <- reactive(subset(CONQDF,input$Demog %in% levels(input$Demog)[1] & CONQDF$VW_Model == input$Car))
output$P1 <- renderPlot({
ggplot(C2(),aes_string(x="CompMake", y=input$Metric))+ geom_bar(stat = "identity")
})
}
shinyApp(ui,server)
The ui works fine, however; the server function generates an empty
plot.
This is most likely due to the fact that the function subset returns an empty dataset. In order to debug the code, first, I would print out in the console this part:
C2 <- reactive(subset(CONQDF,input$Demog %in% levels(input$Demog)[1] & CONQDF$VW_Model == input$Car))
I believe that this part is wrong because input$Demog is just a character string and not a factor. That's why levels(input$Demog) = NULL and input$Demog %in% levels(input$Demog) = FALSE. Hence, as a result, you get an empty dataset.
To check this:
output$P1 <- renderPlot({
print(C2()) # print it out to the console.
ggplot(C2(),aes_string(x="CompMake", y=input$Metric))+ geom_bar(stat = "identity")
})
If this is the case, you only need to re-think subsetting part.
It looks like your C2 function can't see CONQDF (hence the blank plot). You can add () after CONQDF in your C2 call to run that read.csv every time, but you're probably better off moving the read.csv outside your server function altogether.
So move this line
CONQDF <- read.csv("C:/Users/Reginald/Desktop/CONQ_VW/CONQUEST2.csv")
to the top of your script, just below library(dplyr). This will make shiny read that file when the page first loads, instead of every time the input is updated, and will also place the resulting dataframe into the global environment, which will mean your C2 <- call will be able to see it.
I can't easily reproduce your app, so I can't test my answer. Please let me know whether or not it helps.
I have a simple shiny app, I would like to pass the value from the selectInput as a column name of data frame and use it in ggplot. My UI code looks like that:
library(shiny)
# Define UI for application that draws a histogram
shinyUI(fluidPage(
# Application title
titlePanel("Title"),
# Sidebar with a slider input for the number of bins
sidebarLayout(
sidebarPanel(
selectInput(inputId = "yaxis",
label = "Y-axis",
choices = list("Overall Rank" = "overall_rank",
"Income Deprivation" = "income_deprivation_rank"),
selected = "income_deprivation_rank"),
selectInput(inputId = "xaxis",
label = "X-axis",
choices = list("Overall Rank" = "overall_rank",
"Income Deprivation" = "income_deprivation_rank"),
selected = "overall_rank")),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot"),
h5("Notes"),
p("notes")
)
)
))
My server side code is vary simple, I have a SPARQL query (cut here to save the space) that creates simple data frame:
# Libs
require(shiny); require(SPARQL); require(ggplot2)
# Server function
shinyServer(function(input, output) {
# Source the data
## Define endpoint URL.
endpoint <- "http://data.opendatascotland.org/sparql.csv"
### Create Query
query.simd <- "PREFIX stats: <http://statistics.data.gov.uk/id/statistical-geography/>
(...) cut to save space (...)"
## Make the data
dta.simd<- SPARQL(url = endpoint, query = query.simd, format = "csv")$results
## Make the plot
output$distPlot <- renderPlot({
xaxis <- as.character(input$xaxis)
yaxis <- as.character(input$yaxis)
# draw the the plot
ggplot(data = dta.simd, aes(x = xaxis, y = yaxis)) +
geom_point(shape=1)
})
})
The query results in a simple data frame, resambling the extract below:
observation overall_rank income_deprivation_rank
a001 2 6
a002 10 7
a003 11 9
After compiling the app I keep on receiving the Error: object 'xaxis' not found. This leads me to believe that for whatever reason the value from the input$xaxis is not passes to the xaxis object and cannot be used in ggplot. If I decide to replace the as.character(input$yaxis) with a string corresponding to the column name, like for instance overall_rank and the other one income_deprivation_rank the app works as it should, so the problem is clearly associated with using the input$xaxis value. I tried the code with no as.character() function but got the same error message.
Wherever you would normally reference the column name as a string like input$colName, replace it with get(input$colName). This way Shiny knows to fetch the value of input$colName instead of treating it as a string.