如何在不使用update_input类似功能的情况下从外部文件中互动更新默认值(selected =)值



我正在使用基于用户输入创建新数据(Excel)文件的应用程序,还可以让用户重新加载一个先前创建的文件,根据需要显示/更新内容。据我所知,这需要在各种输入函数中更新默认值(selected =)值。

该应用程序的工作原理:用户选择页面和填充数据的数量,每个页面都保存在Excel文件中。当用户想更新文件以添加或删除页面时,用户将从访问限制文件夹中加载Excel文件,每个标签中的数据都在每个页面中填充。然后,用户适当地编辑输入值并保存数据。

我能够使用updatesElectInput和类似功能来更新字段。面临的挑战是,我每个页面有大约30个输入字段,最多需要20页,需要600个更新语句。我正在寻找一种简单有效的方法来实现这一目标。下面给出的例子几乎显示了我要实现的基本概念。

library(shiny)
Sel <- data.frame(list(x = c("Sepal.Length", "Petal.Length","3" )))
ui <- fluidPage(
  pageWithSidebar(
    headerPanel('Iris k-means clustering'),
    sidebarPanel(
      fileInput("File1", "Load File", multiple = FALSE, accept = NULL, width = NULL,
                buttonLabel = "Browse...", placeholder = "No file selected"),
      actionButton("NewValues", "Values from file"), 
      tags$br(),tags$br(),
      selectInput('xcol', 'X Variable', names(iris), selected = Sel$x[1]),
      selectInput('ycol', 'Y Variable', names(iris), selected = Sel$x[2]),
      selectInput('clusters', 'Cluster count', choices = seq(1:9), selected = Sel$x[3])
    ),
    mainPanel(
      plotOutput('plot1')
    )
  )
)
server <- function(input, output) {
  Sel <- eventReactive(input$NewValues, {
    inFile <- input$File1
    read.csv(inFile$datapath, header = TRUE)
     # The output of eventReactive function will be something equivalent to this: 
     # Sel <- data.frame(list(x = c("Petal.Length", "Sepal.Length","5" )))
  })
  selectedData <- reactive({
    iris[, c(input$xcol, input$ycol)]
  })
  clusters <- reactive({
    kmeans(selectedData(), input$clusters)
  })
  output$plot1 <- renderPlot({
    palette(c("#E41A1C", "#377EB8", "#4DAF4A", "#984EA3",
              "#FF7F00", "#FFFF33", "#A65628", "#F781BF", "#999999"))
    par(mar = c(5.1, 4.1, 0, 1))
    plot(selectedData(),
         col = clusters()$cluster,
         pch = 20, cex = 3)
    points(clusters()$centers, pch = 4, cex = 4, lwd = 4)
  })
}
shinyApp(ui = ui, server = server)

加载数据(CSV)文件时,从EventReactive函数创建的Sel数据框将等效于此:

 Sel <- data.frame(list(x = c("Petal.Length", "Sepal.Length","5" )))

这是我可以得到的最接近的:

library(shiny)
Sel2 <- data.frame(list(x = c("Sepal.Length", "Petal.Length","3" )))
ui <- fluidPage(
  pageWithSidebar(
    headerPanel('Iris k-means clustering'),
    sidebarPanel(
      fileInput("File1", "Load File", multiple = FALSE, accept = NULL, width = NULL,
                buttonLabel = "Browse...", placeholder = "No file selected"),
      actionButton("NewValues", "Values from file"), 
      tags$br(),tags$br(),
      uiOutput("select1"),
      #selectInput('xcol', 'X Variable', names(iris), selected = Sel$x[1]),
      #selectInput('ycol', 'Y Variable', names(iris), selected = Sel$x[2]),
      selectInput('clusters', 'Cluster count', choices = seq(1:9), selected = Sel2$x[3])
    ),
    mainPanel(
      plotOutput('plot1')
    )
  )
)
server <- function(input, output) {
  Sel <- eventReactive(input$NewValues, {
    inFile <- input$File1
    read.csv(inFile$datapath, header = TRUE)
    # The output of eventReactive function will be something equivalent to this: 
    # Sel <- data.frame(list(x = c("Petal.Length", "Sepal.Length","5" )))
  })
  output$select1<-renderUI({
    element_number<- length(Sel2$x) - 1 
    lapply(1:element_number, function(i) {
      selectInput(inputId=paste0("col",i),paste0("Col ",i),
                choices = names(iris), selected = Sel2$x[i])})}) 
  selectedData <- reactive({
    element_number<- length(Sel2$x) - 1 
    vector <- lapply(1:element_number, function(i) {
      a <- eval(parse(text=paste0("input$col",i)))})
      b <-unlist(strsplit(as.character(vector), ","))
      data <- iris[, b]
  })
  clusters <- reactive({
    kmeans(selectedData(), input$clusters)
  })
  output$plot1 <- renderPlot({
    palette(c("#E41A1C", "#377EB8", "#4DAF4A", "#984EA3",
              "#FF7F00", "#FFFF33", "#A65628", "#F781BF", "#999999"))
    par(mar = c(5.1, 4.1, 0, 1))
    plot(selectedData(),
         col = clusters()$cluster,
         pch = 20, cex = 3)
    points(clusters()$centers, pch = 4, cex = 4, lwd = 4)
  })
}
shinyApp(ui = ui, server = server)

有一个函数将在文件中的参数长度基础上自动创建 selectInput s,该函数被读取(> bungent -1, (Sel2$x) - 1,因为最后一个参数是cluster number and我找不到可以解决这个问题的简单解决方案,但是如果群集编号始终是最后一个参数,那就不应该是问题):

  output$select1<-renderUI({
    element_number<- length(Sel2$x) - 1 
    lapply(1:element_number, function(i) {
      selectInput(inputId=paste0("col",i),paste0("Col ",i),
                choices = names(iris), selected = Sel2$x[i])})}) 

以及在创建的小部件的基础上,我能够将数据子集以进一步分析:

  selectedData <- reactive({
    element_number<- length(Sel2$x) - 1 
    vector <- lapply(1:element_number, function(i) {
      a <- eval(parse(text=paste0("input$col",i)))})
      b <-unlist(strsplit(as.character(vector), ","))
      data <- iris[, b]
  })

相关内容

最新更新