0

Comrades! Greetings. Please help me out ... there is some significant misunderstanding.

Suppose I created like this data.frame:

df<-data.frame(num = c(1:250),
           app_num =  sample(1:100, 250, replace=T),
           entrance=sample(1:4, 250, replace=T),
           gender=sample(c('m','f'), 250,replace=T),
           age= sample(1:100, 250, replace=T))

I save it in the "*csv" format, using the command:

write.csv2(data_file,file = file.choose(new = T), row.names = FALSE, quote = FALSE)

O.K. Now I want to create a shiny-application for displaying and working with this data like his:

    library("shiny")
    #to work with extra string functions
    library("stringr") 
    library("data.table") 
    library("readr")

    # Define UI for application that draws a histogram
    ui <- fluidPage(
      titlePanel(h2(strong("Analysis of the composition and structure of residents"),
                 align = "center")),
      fileInput(
        inputId="fileInput",
        label="Choose file",
        multiple = FALSE,
        accept = ".csv",
        width = '100%',
        buttonLabel = "Choosing ...",
        placeholder = "No files selected yet"
      ),
      sidebarPanel(
        checkboxGroupInput(inputId="gender", label = "Choosing a gender feature:",
          choices = c("Men" = "m",
                      "Women" = "f"),
          selected= c("Men" = "m",
                      "Women" = "f")),
        sliderInput(inputId = "age", label = "Indicate the age group:",
                    min = 1, max = 100, value = c(1, 100)),
        selectInput(
          inputId = "group",
          label="Indicate the entrance",
          choices=c(1:4),
          selected = c(1:4),
          multiple = TRUE,
          selectize = TRUE,
          width = NULL,
          size = NULL
        )
      ),
      mainPanel(
        navbarPage("",
          tabPanel("Сommon data",
            textOutput(outputId = "text1"),
            ),
          tabPanel("Results table",
                   dataTableOutput(outputId = "content")
            ),
          tabPanel("Graphic data")
        )
      )
    )

    # Define server logic required to draw a histogram
    server <- function(input, output) {

      fileinfor <- reactiveValues(file=NULL,
                                 ext=NULL,
                                 datapath=NULL)
      
      output$content <- renderDataTable({
        fileinfor$file <- input$fileInput
        fileinfor$datapath<-fileinfor$file$datapath
        fileinfor.datapath <- fileinfor$file$datapath
        fileinfor$ext <- tools::file_ext(fileinfor$datapath)
        req(fileinfor$file)
        validate(need(fileinfor$ext== "csv", "Please upload a csv file"))
        fread(fileinfor$datapath,
              showProgress = FALSE,
              sep=";", quote="",header=TRUE)
      })

      output$text1 <- renderUI(renderText({ 
        paste("Check ", fileinfor$datapath)
        }))
      
    }

    # Run the application 
    shinyApp(ui = ui, server = server)

On the server side, I have several questions:

  1. How to get the data correctly so that you can create a variable based on it and use it several times. On the example of my code, you can see that the server-side code block below no longer sees the created variable:

    output $ text1 <- renderUI (renderText ({ paste ("Check", fileinfor $ datapath) }))

  2. Could you show by my example the creation of manipulated variables and their application? Can't figure out where and how to move?

  • Do you plan for the user to upload their own data, or do you plan for the user to only work with data that is already on the server? – da11an Dec 23 '20 at 06:25
  • @YBS Can we continue the discussion? Thank you for your help. –  Dec 24 '20 at 12:18

2 Answers2

0

Perhaps you are looking for this.

server <- function(input, output) {
  
  mydf <- reactive({
    req(input$fileInput)
    inData <- input$fileInput
    if (is.null(inData)){ return(NULL) }
    mydata <- read.csv(inData$datapath, header = TRUE, sep=",")
  })
  
  output$content <- renderDT(mydf())
  
  output$text1 <- renderText({
    req(input$fileInput)
    paste("Check ", input$fileInput$datapath)
  })
  
}
YBS
  • 19,324
  • 2
  • 9
  • 27
  • I am not clear on what you are trying to do with text1. All variables in your dataframe exist for further use. – YBS Dec 21 '20 at 13:08
  • In your example, you create the mydata variable inside the mydf function. You send data to it from a file, as usual in P. Now, for example, I need to use this data in order to further process it and build a graph on it. But this variable no longer exists outside the function. –  Dec 22 '20 at 20:37
  • I would also like to use the results of the table fetch to change the parameters of some controls created in the UI, such as sliderInput. Well that is I would like to calculate the maximum value in the age column and re-configure this control after uploading the file. –  Dec 22 '20 at 20:47
  • 1
    Perhaps, my answer [here](https://stackoverflow.com/questions/65397766/shiny-application-for-linear-regression-with-dynamic-variable-dropdown-based-on/65403395?noredirect=1#comment115644848_65403395) will help you. – YBS Dec 22 '20 at 21:05
0

First of all, I would like to thank @YBS for this teaching. Thanks to these tips, I managed to solve half of the problem.

The essence of the solution lies in how Shainiy works with variables. In fact, there is no way to store variables like when writing regular code. However, you can write a reactive function that will receive data and issue it to a variable that is within the framework of another function when called.

It should be noted that an explicit mention of this approach was found in the tutorial "Mastering Shiny"

As a result, a version of the working code was obtained. If you want to try the end result, then sequentially sell the following steps:

  1. Create a CSV file for our experiment:

    df<-data.frame(num = c(1:250), app_num = sample(1:100, 250, replace=T), entrance=sample(1:4, 250, replace=T), gender=sample(c('m','f'), 250,replace=T), age= sample(1:100, 250, replace=T))

  2. Save it in the "*csv" format, using the command:

    write.csv2(data_file,file = file.choose(new = T), row.names = FALSE, quote = FALSE)

  3. Use the below mentioned code to create Shiny app:

            library("shiny")
            library("stringr")
            library("data.table")
            library("readr")
            library("DT")
            library("readr")
            library("here")
            library("ggplot2")
            library("dplyr")
            library("tidyr")
    
            # Define UI for application that draws a histogram
            ui <- fluidPage(
              titlePanel(h2(strong("Analysis of the composition and structure of residents"),
                         align = "center")),
              fileInput(
                inputId="fileInput",
                label="Choose file",
                multiple = FALSE,
                accept = ".csv",
                width = '100%',
                buttonLabel = "Choosing ...",
                placeholder = "No files selected yet"
              ),
              sidebarPanel(
                checkboxGroupInput(inputId="gender", label = "Choosing a gender feature:",
                  choices = c("Men" = "M",
                              "Women" = "F"),
                  selected= c("Men" = "M",
                              "Women" = "F")),
                sliderInput(inputId = "age", label = "Indicate the age group:",
                            min = 1, max = 100, value = c(1, 100)),
                selectInput(
                  inputId = "group",
                  label="Indicate the entrance",
                  choices=c(1:4),
                  selected = c(1:4),
                  multiple = TRUE,
                  selectize = TRUE,
                  width = NULL,
                  size = NULL
                )
              ),
              mainPanel(
                navbarPage("",
                  tabPanel("РЎommon data",
                    textOutput(outputId = "text1")
                    ),
                  tabPanel("Results table",
                    dataTableOutput(outputId = "content")
                    ),
                  tabPanel("Graphic data",
                    plotOutput(outputId = "my_plot")
                  )
                )
              )
            )
    
            # Define server logic required to draw a histogram
            server <- function(input, output) {
    
              fileinfor <- reactiveValues(file=NULL,
                                          ext=NULL,
                                          datapath=NULL)
    
    
              gender = reactive({
                gender <- input$gender
                gender
                })
              age = reactive({
                cbind(input$age[1],input$age[2])
                })
              group = reactive({
                input$group
                })
    
              import_data <- reactive({
                req(input$fileInput)
                fileinfor$file <- input$fileInput
                if (is.null(input$fileInput)){ return(NULL) }
                fileinfor$datapath<-fileinfor$file$datapath
                fileinfor$ext <- tools::file_ext(fileinfor$datapath)
                validate(need(fileinfor$ext== "csv", "Please upload a csv file"))
                import_data <- fread(fileinfor$datapath,
                      showProgress = FALSE,
                      sep=";", quote="",header=TRUE)
              })
    
    
              output$content <- renderDT({
                GENDER = gender()
                GROUP = group()
                AGE = age()
                req(import_data())
                data_file <- import_data()
                names(data_file) <- c("ID", "App", "Entrance", "Gender", "Age")
                data_file <- mutate_at(data_file, vars(Gender), as.factor)
                data_file<- mutate(data_file, Gender = factor(Gender, labels = c("F", "M")))
                data_file <- subset(data_file,data_file$Age>=AGE[1]
                                    & data_file$Age<=AGE[2]
                                    & data_file$Entrance %in% GROUP
                                    & data_file$Gender %in% GENDER)
                                         })
    
              output$text1 <- renderText({
                req(input$fileInput)
                gender <- gender()
                paste(length(gender))
              })
    
              output$my_plot= reactivePlot(function(){
                GENDER = gender()
                GROUP = group()
                AGE = age()
                req(import_data())
                data_file <- import_data()
                names(data_file) <- c("ID", "App", "Entrance", "Gender", "Age")
                data_file <- mutate_at(data_file, vars(Gender), as.factor)
                data_file<- mutate(data_file, Gender = factor(Gender, labels = c("F", "M")))
                data_file <- subset(data_file,data_file$Age>=AGE[1]
                                    & data_file$Age<=AGE[2]
                                    & data_file$Entrance %in% GROUP
                                    & data_file$Gender %in% GENDER)
    
                df <- group_by(data_file, data_file$Entrance, data_file$Gender)
                df <- summarise(df, N = n())
                names(df) <- c("Entrance", "Gender", "Quantity")
                df <- mutate_at(df, vars(Gender), as.factor)
                print(data_file$Gender)
                #df <- mutate(df, Gender = factor(Gender, levels  = c("f", "m")))
                df <- complete(df, Gender, fill = list(M = 0, F = 0))
    
                baseR.sbst.rssgn <- function(x) {
                  x[is.na(x)] <- 0
                  x
                }
    
                df$Quantity <- baseR.sbst.rssgn(df$Quantity)
    
                ggplot(data = df, aes(x = factor(df$Gender), y = df$Quantity, fill = df$Gender)) +
                  geom_bar(stat = "identity", position = position_dodge2(0.9)) +
                  geom_text(data = df, aes(label = df$Quantity, y = 0), vjust = -0.5, position = position_dodge2(0.9)) +
                  scale_fill_discrete(name = "Title", labels = c("F", "M")) +
                  facet_wrap(~ df$Entrance, nrow = 1, strip.position = "bottom") +
                  xlab("Distribution of residents by entrances, taking into account gender") +
                  ylab("Number of residents") +
                  theme(
                    strip.placement = "outside",
                    strip.background = element_blank(),
                    axis.text.x = element_blank(),
                    axis.ticks.x = element_blank()
                  )
    
    
                #?(ZMlength ~ Month, data = dat[dat$Lake == LAKE, ],
                #        main = "", xlab = "Month", ylab = "Shell length (mm)")
              })
    
    
            }
    
            # Run the application 
            shinyApp(ui = ui, server = server)
    

What problems did I not solve:

  1. I would like to immediately calculate the maximum and minimum values in the "Age" column when opening a file and change the settings for sliderInput. I would like to do the same with selectInput.
  2. I would like to use the Saini application not only to analyze the downloaded data, but also to replenish the CSV file. In this part, I do not know anything at all.
  • Please post a [MRE](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) (minimally reproducible example) for each issue separately. In that process you might solve the problem yourself. If you do post your issue on SO, someone will help you. – YBS Dec 25 '20 at 12:43