Сохранить и загрузить выбор пользователя на основе выбора файла - RShiny - PullRequest
0 голосов
/ 28 октября 2018

Я пытаюсь создать простое приложение, которое действует как графический интерфейс для изучения разных файлов, имеющих одинаковые переменные, но с разной версией и содержанием.Я не могу дать приложение, в котором каждый раз, когда пользователь открывает приложение, ему не нужно снова вводить свои параметры в том месте, где они остановились.Я бы хотел, чтобы они могли сохранять свои параметры и вызывать их снова, когда они вернутся в приложение.

Я даю свой пример кода здесь, однако количество входов и графиков гораздо больше вфактическое приложение.Я хочу знать, есть ли какое-либо решение для сохранения этих зависимых входов и выходов.

library(shiny)
library(pryr)

ui = shinyUI(fluidPage(

  # Application title
  titlePanel("Example Title"),

  # Sidebar structure
  sidebarLayout(
    sidebarPanel(
      textInput("save_file", "Save to file:", value="sample.RData"),
      actionButton("save", "Save input value to file"),
      uiOutput("load"),
      uiOutput("file"),
      uiOutput("mytype"),
      uiOutput("mysubtype")
    ),

    # Show a plot of the generated distribution
    mainPanel(
      tabsetPanel(id="tab",
                  tabPanel(
                    "Plot",
                    plotOutput("distPlot"),
                    checkboxInput(inputId = "density",
                                  label = strong("Show Adjustment Factors"),
                                  value = FALSE),
                    conditionalPanel(condition = "input.density == true",
                                     sliderInput(inputId = "bandwidth",
                                                 label = "Width adjustment: ",
                                                 min = 0.5, max = 4, value = 1, step = 0.1),
                                     radioButtons("mycolor", "Color Adjustment: ",
                                                  choices = c(Red = "red", Black = "black", Blue = "blue"),selected = "black", inline = TRUE)
                    )),
                  tabPanel("Summary",
                           h3(textOutput("label")),
                           verbatimTextOutput("summary")
                  )
      ))

  )
)
)

server = function(input, output, session) {
  # render a selectInput with all RData files in the specified folder
  output$load <- renderUI({
    choices <- list.files("/home/user/Documents/Shiny/", pattern="*.RData")
    selectInput("input_file", "Select input file", choices)
  })

  # render a selectInput with all csv files in the specified folder so that user can choose the version
  output$file <- renderUI({
    choices.1 <- list.files("/home/user/Documents/Shiny/", pattern="*.csv")
    selectInput("input_csv", "Select csv file", choices.1)
  })

  # Load a csv file and update input
  data = eventReactive(input$input_csv, {
    req(input$input_csv)
    read.csv(paste0("/home/user/Documents/Shiny/",input$input_csv),
             header = TRUE,
             sep = ",")
  })

  #Display Type - Types may differ based on file selection
  output$mytype <- renderUI({
    selectInput("var1", "Select a type of drink: ", choices = levels(data()$Type))
  })

  #Display SubType - This would be dependent on Type Selection
  output$mysubtype <- renderUI({
    selectInput("var2", "Select the SubType: ", choices = as.character(data()[data()$Type==input$var1,"Subtype"]))
  })

  # Save input when click the button
  observeEvent(input$save, {
    validate(
      need(input$save_file != "", message="Please enter a valid filename")
    )
    mycolor <- input$mycolor
    mytype = input$var1
    mysubtype = input$var2
    density <- input$density
    bandwidth <- input$bandwidth
    save(bandwidth, density,  mycolor, mytype, mysubtype,
         file=paste0("/home/user/Documents/Shiny/", input$save_file))
    choices <- list.files("/home/user/Documents/Shiny/", pattern="*.RData")
    updateSelectInput(session, "input_file", choices=choices)

    choices.1 <- list.files("/home/user/Documents/Shiny/", pattern="*.csv")
    updateSelectInput(session, "input_csv", choices=choices.1)
  })
  # Load an RData file and update input
  # input$var1, input$var2, input$density, input$bandwidth, input$mycolor),
  observeEvent(c(input$input_file), 
               {
    load(paste0("/home/user/Documents/Shiny/",input$input_file))
    updateSelectInput(session, "var1", choices = levels(data()$Type), selected = mytype)
    updateSelectInput(session, "var2", choices = as.character(data()[data()$Type==mytype,"Subtype"]), selected = mysubtype)
    updateCheckboxInput(session, "density", value = density)
    updateSliderInput(session, inputId = "bandwidth", value=bandwidth)
    updateRadioButtons(session, "mycolor", choices = c(Red = "red", Black = "black", Blue = "blue"), selected = mycolor, inline = TRUE)
  })

  output$distPlot <- renderPlot({

    # generate plot
    x = data()[data()$Type == input$var1 & data()$Subtype == input$var2, c("Alcohol_Content","Price")]
    plot(x$Alcohol_Content, x$Price, type = "l", xlab = "Alcohol content", ylab = "Price",
         main = "Sample Plot",
         col="red",
         lwd=1.5)
    if (input$density)
      plot(x$Alcohol_Content, x$Price, type = "p", xlab = "Alcohol content", ylab = "Price",
           main = "Sample Plot",
           col=input$mycolor,
           lwd=input$bandwidth)


  })


  output$summary <- renderText(summary(data()))

}


shinyApp(ui, server)
  1. Входные CSV-файлы всегда будут храниться в "/ home / user / Documents / Shiny /"
  2. Пользователь может просто нажать «Сохранить в файл:», и он должен сохранить выбранные пользователем данные в «sample.RData», расположенном в том же «/ home / user / Documents / Shiny /».Поэтому я хочу дать selectinput, где пользователь может также выбрать файл .RData.
  3. Пользователь также должен иметь возможность сохранять входные данные на главной панели, которые они будут использовать для изменения диаграммы

Вопросы: -

  1. Большая часть кода работает хорошо, как указано выше, но как я могу сохранить #Display Subtype.
  2. Что произойдет, если я добавлю еще один зависимый список, такой как Type и Subtype?
  3. А также, если я смогу получить некоторую помощь о том, будет ли решение работать для нескольких выбранных входов?.

Любая помощь по коду будет очень признательна.

Фиктивные данные: -

x = data.frame(Type=rep(c("WINE"), 9), Subtype=rep(c("TABLE WINE RED", "TABLE WINE WHITE", "MONTILLA"), each=3), Alcohol_content= c(14, 11.5, 12, 11, 13.5, 11, 12.5, 12, 11.5), Price = c(30.99, 32.99, 29.99, 33.99, 36.99, 34.99, 119, 32.99, 13.99))
y = data.frame(Type=rep(c("REFRESHMENT"), 9), Subtype=rep(c("CIDER ALL", "SPIRIT", "BEER"), each=3), Alcohol_content= c(5, 5.2, 7, 5.3, 6.9, 5, 5, 6, 5), Price = c(9.99, 9.99, 8.99, 9.95, 3.49, 9.99, 12.99, 13.49, 21.99))
bcl_data1 = rbind(x, y)
write.csv(bcl_data1, "bcl_data1.csv")

В каждом типе есть еще много подтипов (Wine, Refreshment).Я почему-то не могу получить значение подтипа с помощью приведенного выше кода, однако при загрузке Sample.RData я вижу var2 = выбранное мной значение.

Я хотел бы знать, как сохранить эти значения, пожалуйста.

1 Ответ

0 голосов
/ 29 октября 2018

Вот рабочая версия вашего кода.Ваша проблема заключалась в одновременном использовании renderUI и updateSelectInput.Каждый раз, когда вы пытались обновить свой selectInput, он сразу отображался заново, чтобы изменения не были видны.Я бы рекомендовал отображать selectInput в пользовательском интерфейсе (который я сделал для «var2») и использовать только updateSelectInput.(Если вы действительно хотите продолжать создавать свои собственные закладки.)

С уважением

library(shiny)
library(pryr)

if(!file.exists("bcl_data1.csv")){
  x = data.frame(Type=rep(c("WINE"), 9), Subtype=rep(c("TABLE WINE RED", "TABLE WINE WHITE", "MONTILLA"), each=3), Alcohol_content= c(14, 11.5, 12, 11, 13.5, 11, 12.5, 12, 11.5), Price = c(30.99, 32.99, 29.99, 33.99, 36.99, 34.99, 119, 32.99, 13.99))
  y = data.frame(Type=rep(c("REFRESHMENT"), 9), Subtype=rep(c("CIDER ALL", "SPIRIT", "BEER"), each=3), Alcohol_content= c(5, 5.2, 7, 5.3, 6.9, 5, 5, 6, 5), Price = c(9.99, 9.99, 8.99, 9.95, 3.49, 9.99, 12.99, 13.49, 21.99))
  bcl_data1 = rbind(x, y)
  write.csv(bcl_data1, "bcl_data1.csv")
}


settings_path <- getwd()
# settings_path <- "/home/user/Documents/Shiny/"

ui = shinyUI(fluidPage(

  # Application title
  titlePanel("Example Title"),

  # Sidebar structure
  sidebarLayout(
    sidebarPanel(
      textInput("save_file", "Save to file:", value="sample.RData"),
      actionButton("save", "Save input value to file"),
      p(),
      p(),
      uiOutput("load"),
      uiOutput("file"),
      uiOutput("mytype"),
      selectInput("var2", "Select the SubType: ", choices = NULL)
    ),

    # Show a plot of the generated distribution
    mainPanel(
      tabsetPanel(id="tab",
                  tabPanel(
                    "Plot",
                    plotOutput("distPlot"),
                    checkboxInput(inputId = "density",
                                  label = strong("Show Adjustment Factors"),
                                  value = FALSE),
                    conditionalPanel(condition = "input.density == true",
                                     sliderInput(inputId = "bandwidth",
                                                 label = "Width adjustment: ",
                                                 min = 0.5, max = 4, value = 1, step = 0.1),
                                     radioButtons("mycolor", "Color Adjustment: ",
                                                  choices = c(Red = "red", Black = "black", Blue = "blue"),selected = "black", inline = TRUE)
                    )),
                  tabPanel("Summary",
                           h3(textOutput("label")),
                           verbatimTextOutput("summary")
                  )
      ))

  )
)
)

server = function(input, output, session) {
  # render a selectInput with all RData files in the specified folder
  last_save_path <- file.path(settings_path, "last_input.backup")
  if(file.exists(last_save_path)){
    load(last_save_path)
    if(!exists("last_save_file")){
      last_save_file <- NULL
    }
  } else {
    last_save_file <- NULL
  }

  if(!is.null(last_save_file)){
   updateTextInput(session, "save_file", "Save to file:", value=last_save_file)
  }

  output$load <- renderUI({
    choices <- list.files(settings_path, pattern="*.RData")
    selectInput("input_file", "Select input file", choices, selected = last_save_file)
  })

  # render a selectInput with all csv files in the specified folder so that user can choose the version
  output$file <- renderUI({
    choices.1 <- list.files(settings_path, pattern="*.csv")
    selectInput("input_csv", "Select csv file", choices.1)
  })

  # Load a csv file and update input
  csv_data = eventReactive(input$input_csv, {
    req(input$input_csv)
    read.csv(file.path(settings_path,input$input_csv),
             header = TRUE,
             sep = ",")
  })

  #Display Type - Types may differ based on file selection
  output$mytype <- renderUI({
    req(csv_data())
    selectInput("var1", "Select a type of drink: ", choices = unique(csv_data()$Type))
  })

  #Display SubType - This would be dependent on Type Selection
  observeEvent(input$var1, {
    req(csv_data())
    req(input$var1)
    updateSelectInput(session, "var2", "Select the SubType: ", choices = as.character(csv_data()[csv_data()$Type==input$var1,"Subtype"]), selected = isolate(input$var2))
  })

  # Save input when click the button
  observeEvent(input$save, {
    validate(
      need(input$save_file != "", message="Please enter a valid filename")
    )

    last_save_file <- input$save_file
    save(last_save_file,  file=last_save_path)

    mycolor <- input$mycolor
    mytype = input$var1
    mysubtype = input$var2
    density <- input$density
    bandwidth <- input$bandwidth
    save(bandwidth, density,  mycolor, mytype, mysubtype,
         file=file.path(settings_path, input$save_file))
  })

  # Load an RData file and update input
  observeEvent(input$input_file, {
    req(input$input_file)
    load(file.path(settings_path, input$input_file))
    updateSelectInput(session, "var1", choices =  unique(csv_data()$Type), selected = mytype)
    updateSelectInput(session, "var2", choices = mysubtype, selected = mysubtype)
    updateCheckboxInput(session, "density", value = density)
    updateSliderInput(session, "bandwidth", value = bandwidth)
    updateRadioButtons(session, "mycolor", choices = c(Red = "red", Black = "black", Blue = "blue"), selected = input$mycolor)
  })

  output$distPlot <- renderPlot({
    req(csv_data())
    req(input$var1)
    req(input$var2)

    # generate plot
    x = csv_data()[csv_data()$Type == input$var1 & csv_data()$Subtype == input$var2, c("Alcohol_content",  "Price")]
    if(nrow(x) > 0){
      x <- x[order(x$Alcohol_content), ]
      plot(x$Alcohol_content, x$Price, type = "l", xlab = "Alcohol content", ylab = "Price",
           main = "Sample Plot",
           col="red",
           lwd=1.5)
      if (input$density)
        plot(x$Alcohol_content, x$Price, type = "p", xlab = "Alcohol content", ylab = "Price",
             main = "Sample Plot",
             col=input$mycolor,
             lwd=input$bandwidth)
    }

  })


  output$summary <- renderText(summary(csv_data()))

}

shinyApp(ui, server)
...