0

I am very new to Shiny web app with R. I want to generate summary according to choice from checkboxGroupInput which i generated dynamically when browsing the CSV file. My problem is that when i want to convert from String to numeric that time it prints NA. I am uploading my two files which are ui.r and server.r. I am trying since two days. If anyone help me then it will be very beneficial for me.

If i did anything wrong in my code then please suggest me right way.

ui.r

library(shiny)
library(shinythemes)


shinyUI(fluidPage(

  theme = shinytheme("cyborg"),
  themeSelector(),
 # Application title
  titlePanel("Data Analytics and Visualization Dashboard"),


  sidebarLayout(
  sidebarPanel(
  fileInput('datafile', 'Choose CSV file',accept=c('text/csv', 'text/comma- 
  separated-values,text/plain')),
  h5("Max file size to upload is 5 MB."),
  radioButtons("sep", "Seperator", choices = c(Comma = ',', semicolon = ';', 
  tab = "\t", space = " " )),
  #checkboxInput("header", "Header?")

  br(),

   h4("Select columns from CSV"),

  uiOutput("toCol"),
  br(),

  h4("Summary"),
  textOutput("sum")
  # tableOutput("disp")
  ),


mainPanel(
  numericInput("obs", "Enter the number of rows to display:", 5),

  tableOutput("input_file"),
  plotOutput("p")



 )
 )
 ))

server.r

library(shiny)

shinyServer(function(input, output,session) {


#This function is repsonsible for reading a csv file
output$input_file <- renderTable({

file_to_read = input$datafile
if(is.null(file_to_read))
{
  return()
}

read.csv(file_to_read$datapath, sep = input$sep, nrows = input$obs))

 })


 #This function is repsonsible for loading in the selected file
 filedata <- reactive({
    infile <- input$datafile
    if (is.null(infile)) {
    # User has not uploaded a file yet
      return(NULL)
  }

  read.csv(infile$datapath,nrows = input$obs)
   })

  #The following set of functions populate the column selectors
  output$toCol <- renderUI({
    df <-filedata()
     if (is.null(df)) return(NULL)
       items=names(df)
       names(items)=items
       checkboxGroupInput("to", "Columns",items)

   })

   observe({
      # db <- gsub(",","",input$to)
       #  print(db)
       # paste( intToUtf8(160), input$to, intToUtf8(160))

      # print(summary(as.numeric(as.character(  paste( " ", input$to, " 
       #"))))) })
     print(summary(as.numeric( input$to) ))})
     # output$sum <- renderPrint({

    #   summary(input$data.frame[,as.numeric(input$var)])
    #  })

       # output$disp <- renderTable({
      #    input$to
       # })

   # output$summary1 <- renderPrint({
    #    sum <- as.numeric(as.character(input$to))
   # summary(sum)
   #})
     })
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
Heena
  • 61
  • 2
  • 10
  • I am unable to find the line of your error `summary(as.numeric(paste(input$to, “input$to”)))` in your code. Did you mean `print(summary(as.numeric( input$to) ))` ? –  May 17 '18 at 07:33
  • 1
    Hi Heena, Welcome to Stackoverflow. Please go through [this](https://stackoverflow.com/questions/48343080/how-to-convert-a-shiny-app-consisting-of-multiple-files-into-an-easily-shareable) question specifically meant on how to share a shiny example. – Ronak Shah May 17 '18 at 07:42
  • `checkboxGroupInput("to", "Columns",items)` where "to" is the id of checkboxGroupInput. i print the summary in console using `print(summary(as.numeric( input$to) ))` so i can get the number of fields selected by user from checkboxGroupInput. I want to generate summary dynamically when i do check the checkboxGroupInput. @Codeer – Heena May 17 '18 at 08:33

2 Answers2

0

Like @Codeer said, there is no line in your code like this one summary(as.numeric(paste(input$to, “input$to”))). I edited your code, so all the uncommented lines dont appear, as its not necessary to show them.

In your example, your loading the csv file twice, which you can definitly avoid. I moved the csv-loading into the reactive only. Then you can access the loaded file everywhere in your shiny-app. And i think in your print(summary()) statement, you're missing the data, as your only printing out the summary of the input$tovariable, which is only text and if you convert it to numeric you create NA-values.

So i rearranged your code a bit, and I think its behaving the way you intend it to.

library(shiny)
library(shinythemes)

ui <- {shinyUI(fluidPage(
  theme = shinytheme("cyborg"),
  themeSelector(),
  titlePanel("Data Analytics and Visualization Dashboard"),
  sidebarLayout(
    sidebarPanel(
      fileInput('datafile', 'Choose CSV file',accept=c('text/csv', 'text/comma- 
                                                       separated-values,text/plain')),
      h5("Max file size to upload is 5 MB."),
      radioButtons("sep", "Seperator", choices = c(Comma = ',', semicolon = ';', 
                                                   tab = "\t", space = " " )),
      br(),
      h4("Select columns from CSV"),
      uiOutput("toCol"),
      br(),
      h4("Summary"),
      textOutput("sum")
      ),
    mainPanel(
      numericInput("obs", "Enter the number of rows to display:", 5),
      tableOutput("input_file"),
      verbatimTextOutput("summary"),
      plotOutput("p")
    )
  )
  ))}

server <- shinyServer(function(input, output,session) {

  #This function is repsonsible for loading and reading a csv file
  filedata <- reactive({
    req(input$datafile)
    infile <- input$datafile
    if (is.null(infile)) {
      # User has not uploaded a file yet
      return(NULL)
    }
    read.csv(infile$datapath,nrows = input$obs, sep = input$sep)
  })

  output$input_file <- renderTable({
    filedata()
  })

  #The following set of functions populate the column selectors
  output$toCol <- renderUI({
    df <- filedata()
    if (is.null(df)) return(NULL)
    items=names(df)
    names(items)=items
    checkboxGroupInput("to", "Columns",items)
  })

  output$summary <- renderPrint({
    req(input$to)
    data <- filedata()
    print(summary(data[,input$to]))
  })
})

shinyApp(ui, server)

The csv file is loaded in the reactive (filedata). In the renderTable, you just enter the reactive variable - filedata(). And in the observe, you call again the reactive variable and only print out the summary of the data in the clicked column (input$to).

SeGa
  • 9,454
  • 3
  • 31
  • 70
  • Thanks a lot. But I want to display the summary in the web browser. I don't want to print it in the console. How can I print the summary in the web browser using `observe` event? @SeGa – Heena May 17 '18 at 09:06
  • Why do you need an observe and why not put it directly in a renderPrint function? I'll update my code, so it prints out in the web. – SeGa May 17 '18 at 09:08
  • Thanks a lot Sir. @SeGa – Heena May 17 '18 at 09:31
  • You're welcome. If that answers your question, could you mark it as checked? – SeGa May 17 '18 at 17:39
  • Yes. I checked it. Sir, I also have uploaded my second question. Would you like to help me? – Heena May 18 '18 at 05:49
  • What is your second question? – SeGa May 18 '18 at 08:41
  • Sir... I have a question that i want to make login page and if login successfull then i want to open the another ui.r and server.r file. How can i redirect the file from one to another? I'm trying since 5 hours but i don't know how to do that. – Heena May 22 '18 at 09:35
  • I would suggest you go over the following articles [link1](https://auth0.com/blog/adding-authentication-to-shiny-server/),[link2](https://stackoverflow.com/questions/41168459/r-shiny-user-authentication-for-single-app-r), [link3](https://www.r-bloggers.com/add-authentication-to-shiny-server-with-nginx/) . If you are using Shiny Server Pro, there is an authentication module. [Shiny Pro](https://support.rstudio.com/hc/en-us/articles/219045987-Shiny-Server-Quick-Start-Require-user-authentication-on-an-application-Pro-only-) – SeGa May 22 '18 at 12:30
0

This could be a starting point, although I dont recommend using this for a productive app, as the login-process is not really safe nor encrypted. It is based solely on text-data.

But you will have to put the ui in the server and render the page depending on the login status. So there are 2 renderUI but just 1 server-function. I dont know if you can have 2 different server-functions and redirect them. I think it all has to be in 1 server-function.

library(shiny)

username = "joe"
password = "joe123"


ui <- fluidPage(
  uiOutput("ui")
)

server <- function(input, output, session) {

  LOGGED <- reactiveValues(user = FALSE)

  observeEvent(input$action, {
    if ((input$name == username ) & (input$pass == password)) {
      LOGGED$user = TRUE
    } else {
      LOGGED$user = FALSE
    }
  })

  observe({
    if (LOGGED$user == FALSE) {
      output$ui <- renderUI({
        tagList(
          p(HTML("User is joe <br> and password is joe123")),
          textInput("name", "Enter your username"),
          passwordInput("pass", "Enter your password"),
          actionButton("action", label = "Action")
        )
      })
    } else if (LOGGED$user == TRUE) {
      output$ui <- renderUI({
        tagList(
          h1("You are logged in.")
        )
      })
    }
  })
}

shinyApp(ui, server)
SeGa
  • 9,454
  • 3
  • 31
  • 70