【问题标题】:Upload a file in a shiny app and set its name through a textInput()在闪亮的应用程序中上传文件并通过 textInput() 设置其名称
【发布时间】:2018-10-12 14:38:43
【问题描述】:

我在下面有一个简单的闪亮应用程序。在这个应用程序中,我希望用户能够上传他自己的 csv,然后自动将其作为选项添加到另一个数据集“DB”(我在原始应用程序中创建)下方的复选框组中。我通过使用一个观察者和一个记录文件名的反应列表来做到这一点。新文件最初将具有其默认名称,但随后用户将能够使用“设置文件名”textInput() 将其更改为他选择的名称。然后当用户选择一个文件时,它将显示为一个表格。问题是我遗漏了一些东西,当我添加第二个文件时,第一个文件变为 NA 并且没有显示任何表格。

#ui.r
library(shiny)
library(rlist)
# Define UI for data upload app ----
ui <- fluidPage(

  # App title ----
  titlePanel("Uploading Files"),

  # Sidebar layout with input and output definitions ----
  sidebarLayout(

    # Sidebar panel for inputs ----
    sidebarPanel(

      # Input: Select a file ----
      fileInput("file1", "Choose CSV File",
                multiple = FALSE,
                accept = c("text/csv",
                           "text/comma-separated-values,text/plain",
                           ".csv")),
      uiOutput("checkbox"),
      uiOutput("text")

    ),

    # Main panel for displaying outputs ----
    mainPanel(

      # Output: Data file ----
      tableOutput("contents")

    )

  )
)
#server.r
server <- function(input, output) {
  output$text<-renderUI({
  textInput("filename","Set Filename",value = "Set Name")
  })
  New <- reactive({
    req(input$file1)
    df <- read.csv(input$file1$datapath)

  })

  D.B <- reactive({
    if("D.B"%in% input$datasetSelector){
    x <- read.csv("something.csv", stringsAsFactors = F)
    }
  })

  fileOptions <- reactiveValues(currentOptions=c("D.B."))

  observeEvent(input$file1, {
    fileOptions$currentOptions = list.append(fileOptions$currentOptions, "New")
  })
  output$checkbox<-renderUI({
    if(length(fileOptions$currentOptions)==1){
    checkboxGroupInput("datasetSelector","Specify the datasets to compare:", choices = fileOptions$currentOptions[[1]]
    )}
    else{
    names(fileOptions$currentOptions)[[2]]<-input$filename  
    checkboxGroupInput("datasetSelector","Specify the datasets to compare:", choices = fileOptions$currentOptions
   )}
  })
  output$contents <- renderTable({
    input$dataSelector
  })


}

【问题讨论】:

  • 据我所知,该应用程序无法存储多个文件。上传文件后,它被分配为“file1”,如果您要上传另一个文件,它将覆盖“file1”。这是预期的结果吗?就像你想只显示“DB”和选择的任何文件一样吗?
  • 虽然我现在无法尝试并提出具体的潜在解决方案,但建议你看看shinyFiles,它可能会解决这个问题的一半。
  • 文件也应该显示为表格。就像一个文件名。

标签: r shiny


【解决方案1】:

我不得不对服务器和用户界面进行大修,以使用内置的闪亮功能来简化此操作。话虽如此,这可以满足您的所有需求。请注意,我在这里没有展示任何表格制作或数据处理,只是文件重命名和上传。

# Define UI for data upload app ----
ui <- fluidPage(

  # App title ----
  titlePanel("Uploading Files"),

   # Sidebar layout with input and output definitions ----
  sidebarLayout(

    # Sidebar panel for inputs ----
    sidebarPanel(

       # Input: Select a file ----
       fileInput("file1", "Choose CSV File",
                multiple = FALSE,
                accept = c("text/csv",
                       "text/comma-separated-values,text/plain",
                       ".csv")),
      checkboxGroupInput("datasetSelector","Data Files", choices=c("D.B")),
      textInput("filename","Set Filename",value = "Set Name")

    ),

    # Main panel for displaying outputs ----
      mainPanel(

      # Output: Data file ----
      tableOutput("contents")

    ) 
  )
)
#server.r
server <- function(input, output, session) {

  observeEvent(input$filename, {

  req(input$file1)
  Name<-input$filename
  updateCheckboxGroupInput(session,"datasetSelector", choices=c("D.B",Name))
  })

  observeEvent(input$file1, {

    Data<-input$file1$datapath
    Name<-input$filename
    New <- read.csv(Data)
    updateCheckboxGroupInput(session,"datasetSelector", 
      choices=c("D.B",input$file1$name))
  })

  #Data proccesing code 
}

我使用了 checkboxGroupInput 和 textInput,它们是可以在 UI 中定义的闪亮输入。这些设置了标准输入,并允许我们使用像 updateGroupCheckboxInput 这样的函数,这些函数不能用于一般的 UI 渲染。现在我们可以观察到fileInput 和textInput 的任何输入,并根据何时完成运行代码。

当用户上传文件时,复选框的名称设置为上传的文件名。当用户更改input$filename 时,我们可以观察到并相应地更改复选框名称。这样,无论何时上传新文件,它都会用上传的新文件名覆盖现有的复选框名称,而新文件名又可以被我们文本字段的任何输入覆盖。

摆脱响应式 DB 并简单地观察复选框中的任何输入,我们可以简单地根据选中的框数分配数据,因为如果选中了两个,我们应该加载 DB 和上传的文件;如果选中一个,我们可以检查“D.B”的名称、分配的文件名或文本字段名称,并相应地显示正确的文件。 D.B 文件始终加载,而输入文件仅在选中复选框时才加载。由于没有复选框,除非有上传的文件,所以应该在那里覆盖我们。

#Data Processing Code
observeEvent(input$datasetSelector, {

  #Constant
  D.B<- read.csv("somthing.csv", stringsAsFactors = F)

  Selected<-input$datasetSelector
  L_Sel<-length(Selected)

  if(L_Sel==2){
    Data<-read.csv(input$file1$datapath)
    dataSelector<-list(Data,D.B)
    print("A")
  }else if(Selected=="D.B"){
    dataSelector<-D.B
    print("B")
  }else if(Selected==input$file1$name|Selected==input$filename){
    Data<-read.csv(input$file1$datapath)
    dataSelector<-Data
    print(Data)
    print("C")
  }else{
    dataSelector=NA
  }

  output$contents<-renderTable({
    dataSelector
  })

  })

请注意,我们还将输出置于复选框的 observeEvent 下,因此除非您在部署时为复选框设置选定值,否则不会初始化表。我不知道你想如何显示这两个表,所以这需要一些工作,但只需在 if/statement 和 observeEvent 中工作即可。

程序知道两个复选框何时被选中并列出两个文件/数据,但我不确定您打算如何显示这些。不过,您可能希望将这项工作包含在 if(L_Sel==2){..} 部分下。

【讨论】:

  • Tnx 以获得您的详细答案,但我如何也可以使用我上传的文件并将其显示为表格?
  • 很遗憾,如果我无法使用该表,我将无法使用此方法。
  • @firmo23 你搞定表格了吗?
  • 我正在研究解决方案,但如果您有方法,请不要犹豫在这里分享
  • 您能否为 6 个默认数据集而不是一个提供此解决方案?我认为这可能有效
猜你喜欢
  • 2014-12-29
  • 2019-02-13
  • 2021-02-04
  • 2018-06-08
  • 2014-04-11
  • 1970-01-01
  • 2017-04-12
  • 2017-07-10
  • 1970-01-01
相关资源
最近更新 更多