Shiny: Plotting from user uploaded data

Dear colleagues,

I am working on a shiny app in which I am attempting to accept a CSV upload from the user and then create a ggplot from the uploaded file.

Here is a reprex of my UI logic:

tabPanel("Upload", 
        sidebarLayout(
            sidebarPanel(
                fileInput("file1", "Choose CSV File",
                          accept = c(
                              "text/csv",
                              "text/comma-separated-values,text/plain",
                              ".csv")
                ),
                tags$hr(),
                checkboxInput("header", "Header", TRUE)
            ),
            mainPanel(
                tableOutput("contents"),plotOutput("upload"),
            )
        )
        
    )
#> Error in tabPanel("Upload", sidebarLayout(sidebarPanel(fileInput("file1", : could not find function "tabPanel"

Server logic:

 output$contents <- renderTable({
        
        inFile <- input$filedata
        
        if (is.null(inFile))
            return(NULL)
        
    })
#> Error in renderTable({: could not find function "renderTable"
#> Error in renderTable({: could not find function "renderTable"
    
    output$upload <- renderPlot({
        inFile <- input$file1
        
        if (is.null(inFile))
            return(NULL)
        
        uploadr<-read.csv(inFile$datapath, header = input$header)
        uploadr %>%
            ggplot(aes(x=Product, y=Stock))+geom_col()
    })
#> Error in renderPlot({: could not find function "renderPlot"
#> Error in renderPlot({: could not find function "renderPlot"

Any ideas on what's going wrong here? My app is currently returning the error message: duplicate 'row.names' are not allowed.

Thank you for your help in advance. I've been stuck on this for quite some time, so any insight would be greatly appreciated.

Is you error occurring in your table output or your plot output? The code in your renderTable section is not actually displaying the table but just displaying a (nonexistent?) input. You should probably read your users filepath in a reactive and then pass that to the plot and table:

function(input, output, session){
  user_data <- reactive({
    if (is.null(input$file1)) return(NULL)
    read.csv(input$file1$datapath, header = input$header)
  })

  output$contents <- renderTable({
    req(user_data()) # if user_data() is null than the reactive will not run

    user_data()
  })

  output$upload <- renderPlot({
    req(user_data())

    if (all(c("Product", "Stock") %in% colnames(user_data()))) return(NULL) # make sure your target columns in dataset uploaded
    ggplot(user_data(), aes(x = Product, y = Stock)) + 
      geom_col()
  })
}

Hello,

Thank you for your help. I tried this and it seemed to now produce " duplicate 'row.names' are not allowed" 2 times instead of once. Any idea on what this error message means?

it looks like you have to add row.names = NULL to the read.csv function according to this SO post

Awesome. This works in displaying the table, but the plot doesn't yet appear. Does the object need to be printed inside of the renderPlot in order to make it work?