Shiny - upload a csv file, choose columns and let it make a boxplot or a barplot

plotly

#1

Hello everybody,

I am quite new to shiny and I wanted to make it possible to upload a csv file, choose columns and let it make a boxplot or a barplot. On my local pc it works quite fine (but I also get error messages, but it still works), but when I load it up at shinyapps.io I get an error message and nothing works anymore.
Could somebody help me?

library(shiny)
library(datasets)
library(plotly)
library(dplyr)
ui <- shinyUI(fluidPage(
  titlePanel("Visualisierung von Daten"),
  tabsetPanel(
    tabPanel("Upload File",
             titlePanel("Uploading Files"),
             sidebarLayout(
               sidebarPanel(
                 fileInput('file1', 'Wähle eine CSV Datei aus',
                           accept=c('text/csv', 
                                    'text/comma-separated-values,text/plain', 
                                    '.csv')),
                 
                 # added interface for uploading data from
                 # http://shiny.rstudio.com/gallery/file-upload.html
                 tags$br(),
                 checkboxInput('header', 'Kopfzeile', TRUE),
                 selectInput('xcol', 'Spalte:', ""),
                 selectInput('ycol', 'Gruppierungsvariable auswählen (bsp: Alter, Geschlecht,...)', "", selected = ""),
                 selectInput("plot.type","Plot Typ:",
                             list(bar = "bar", boxplot = "boxplot")#, histogram = "histogram", density = "density")
                 ),
                 radioButtons('sep', 'Trennzeichen',
                              c(Semicolon=';',
                                Comma=',',
                                Tab='\t'),
                              ';'),
                 radioButtons('quote', 'Quote',
                              c(None='',
                                'Double Quote'='"',
                                'Single Quote'="'"),
                              '"')
                
               ),
               mainPanel(
                 plotlyOutput('MyPlot')#,
                 # tableOutput('contents')
               )
             )
    )
  )
)
)

server <- shinyServer(function(input, output, session) {
  # added "session" because updateSelectInput requires it
  
  
  data <- reactive({ 
    req(input$file1) ## ?req #  require that the input is available
    
    inFile <- input$file1 
    
    # tested with a following dataset: write.csv(mtcars, "mtcars.csv")
    # and                              write.csv(iris, "iris.csv")
    df <- read.csv(inFile$datapath, header = input$header, sep = input$sep,
                   quote = input$quote)
    for(i in seq_along(df)){
      df[,i] <- as.factor(df[,i])
    }
    
    
    # Update inputs (you could create an observer with both updateSel...)
    # You can also constraint your choices. If you wanted select only numeric
    # variables you could set "choices = sapply(df, is.numeric)"
    # It depends on what do you want to do later on.
    
    updateSelectInput(session, inputId = 'xcol', label = 'Spalte',
                      choices = names(df), selected = names(df))
    updateSelectInput(session, inputId = 'ycol', label = 'Gruppierungsvariable auswählen (bsp: Alter, Geschlecht,...)',
                      choices = names(df), selected = names(df)[2])
    
    return(df)
  })
  
  # output$contents <- renderTable({
  #   data()
  # })

  
  output$MyPlot <- renderPlotly({
  
  if(input$plot.type == "boxplot"){
    p <- ggplot(data(), aes(x=data()[,input$ycol],y=data()[,input$xcol], fill =data()[,input$ycol]))+
      geom_boxplot()+ ggtitle("Boxplot")+
      xlab(input$ycol)+ylab(input$xcol) +scale_fill_discrete(name=input$ycol)
    ggplotly(p) %>% layout(autosize=TRUE)# %>% style(hoverinfo = "none")
  }else{
    if(input$plot.type == "bar"){
      p <-  ggplot(data(),aes(x=data()[,input$xcol],fill=data()[,input$ycol],group = data()[,input$ycol]))+
        geom_bar(aes(y=..prop..),position=position_dodge())+
        ggtitle("Prozentwerte pro Gruppe")+
        xlab(input$xcol)+ylab("Prozent") +scale_fill_discrete(name=input$ycol)
      ggplotly(p) %>% layout(autosize=TRUE) %>% style(hoverinfo = "none")
  # } else {
  #   if(input$plot.type == "histogram"){
  #     p <-  ggplot(data(),aes(x=data()[,input$xcol],fill=data()[,input$ycol],group = data()[,input$ycol]))+
  #       geom_histogram()+
  #       ggtitle("Histogramm")+
  #       xlab(input$xcol) +scale_fill_discrete(name=input$ycol)
  #     ggplotly(p) %>% layout(autosize=TRUE) %>% style(hoverinfo = "none")
  #   }
  }}
    
  })
  
  
  
  
})

shinyApp(ui, server)


#2

I have solved it , but I don't know, how to close the topic :slight_smile:


#3

You can follow this FAQ guide


#4

Hi good day.
Show the solution please.
Thanks


#5

The solution is in my first post. I changed it. It works quite fine. But it could still be improved. German Umlauts like ä,ö,ü are not working (if they are in the header of the csv-file).


library(shiny)
library(datasets)
library(plotly)
library(dplyr)
ui <- shinyUI(fluidPage(
  titlePanel("Visualisierung von Daten"),
  tabsetPanel(
    tabPanel("Upload File",
             titlePanel("Uploading Files"),
             sidebarLayout(
               sidebarPanel(
                 fileInput('file1', 'W\u00e4hle eine CSV Datei aus',
                           accept=c('text/csv', 
                                    'text/comma-separated-values,text/plain', 
                                    '.csv')),
                 
                 # added interface for uploading data from
                 # http://shiny.rstudio.com/gallery/file-upload.html
                 tags$br(),
                 checkboxInput('header', 'Kopfzeile', TRUE),
                 selectInput('xcol', 'Spalte:', ""),
                 selectInput('ycol', 'Gruppierungsvariable ausw\u00e4hlen (bsp: Alter, Geschlecht,...)', "", selected = ""),
                 selectInput("plot.type","Plot Typ:",
                             list(bar = "bar", boxplot = "boxplot")#, histogram = "histogram", density = "density")
                 ),
                 radioButtons('sep', 'Trennzeichen',
                              c(Semicolon=';',
                                Comma=',',
                                Tab='\t'),
                              ';'),
                 radioButtons('quote', 'Quote',
                              c(None='',
                                'Double Quote'='"',
                                'Single Quote'="'"),
                              '"')
                 
               ),
               mainPanel(
                 plotlyOutput('MyPlot')#,
                 # tableOutput('contents')
               )
             )
    )
  )
)
)

server <- shinyServer(function(input, output, session) {
  # added "session" because updateSelectInput requires it
  options(warn=-1)
  # options(encoding="UTF-8")
  
  data <- reactive({ 
    req(input$file1) ## ?req #  require that the input is available
    
    inFile <- input$file1 
    
    # tested with a following dataset: write.csv(mtcars, "mtcars.csv")
    # and                              write.csv(iris, "iris.csv")
    df <- read.csv(inFile$datapath, header = input$header, sep = input$sep,
                   quote = input$quote)
    for(i in seq_along(df)){
      df[,i] <- as.factor(df[,i])
      
    }
    df[df=="NA"] <- NA
    
    
    # Update inputs (you could create an observer with both updateSel...)
    # You can also constraint your choices. If you wanted select only numeric
    # variables you could set "choices = sapply(df, is.numeric)"
    # It depends on what do you want to do later on.
    
    updateSelectInput(session, inputId = 'xcol', label = 'Spalte',
                      choices = names(df), selected = names(df))
    updateSelectInput(session, inputId = 'ycol', label = 'Gruppierungsvariable ausw\u00e4hlen (bsp: Alter, Geschlecht,...)',
                      choices = names(df), selected = names(df)[2])
    
    return(df)
  })
  
  # output$contents <- renderTable({
  #   data()
  # })
  
  
  output$MyPlot <- renderPlotly({
    
    if(input$plot.type == "boxplot"){
      p <- ggplot(na.omit(data()), aes(x=na.omit(data())[,input$ycol],y=na.omit(data())[,input$xcol], fill =na.omit(data())[,input$ycol]))+
        geom_boxplot(na.rm = TRUE)+ ggtitle("Boxplot")+
        xlab(input$ycol)+ylab(input$xcol) +scale_fill_discrete(name=input$ycol)
      ggplotly(p) %>% layout(autosize=TRUE)# %>% style(hoverinfo = "none")
    }else{
      if(input$plot.type == "bar"){
        p <-  ggplot(data(),aes(x=as.factor(data()[,input$xcol]),fill=as.factor(data()[,input$ycol]),group = as.factor(data()[,input$ycol])))+
          geom_bar(aes(y=..prop..*100),position=position_dodge())+
          ggtitle("Prozentwerte pro Gruppe")+
          xlab(input$xcol)+ylab("Prozent") +scale_fill_discrete(name=input$ycol)
        ggplotly(p) %>% layout(autosize=TRUE) %>% style(hoverinfo = "none")
        # } else {
        #   if(input$plot.type == "histogram"){
        #     p <-  ggplot(data(),aes(x=data()[,input$xcol],fill=data()[,input$ycol],group = data()[,input$ycol]))+
        #       geom_histogram()+
        #       ggtitle("Histogramm")+
        #       xlab(input$xcol) +scale_fill_discrete(name=input$ycol)
        #     ggplotly(p) %>% layout(autosize=TRUE) %>% style(hoverinfo = "none")
        #   }
      }}
    
  })
  
  
  
  
})

shinyApp(ui, server)


#6

For nexr time, please to edit the post but add another post to the discussion even if your reply yourself.
First because a question is as important as an answer. Also because the rest of the discussion does not make any sense of you edit the first post. Not cool for readers. :wink:

Glad you found a solution!