根据用户上传数据后选择的用户输入过滤数据框

Posted

技术标签:

【中文标题】根据用户上传数据后选择的用户输入过滤数据框【英文标题】:Filtering a data frame based on user input selected after user uploads data 【发布时间】:2019-10-12 14:56:45 【问题描述】:

我正在构建一个允许用户上传数据文件和 然后使用标准方法分析数据。分析依赖 在上传文件后填充的一个用户输入参数上。

流程是:

    用户上传 .csv 文件。 uiOutput() 填充了 上传数据。 用户在 uiOutput() 中选择一个选项 用户点击“运行分析”。 表格显示结果。 用户可以将分析结果表下载为 .csv。

分析的第 4 步应根据第 3 步的输入过滤数据。

我在服务器函数中使用 renderUI 来根据用户上传的文件的变量中的唯一名称(级别)进行选择。根据之前对 SO 的回答,我使用了 uiOutput,而不是 ui 中的 selectInput()。这允许根据上传的数据填充输入。但这实际上是一个 renderUI 的输出。我想要这个选项来过滤数据,但是我不知道如何指定这个过滤条件。

感兴趣的代码块是####根据用户输入运行分析####

library(shiny)
library(shinythemes)
library(shinyWidgets)
library(dplyr)
library(DT)
library(shinyjs)
library(dplyr)
library(tidyr)
library(stringr)


data_example <- structure( # save as .csv and upload to app
    list(
        site = c("A", "A", "A"),
        analyte = c("x", "y",
                    "z"),
        QA = c(4L, 6L, 3L),
        A1 = c(2L, 6L, 5L),
        A2 = c(1L, 8L,
               4L),
        A3 = c(8L, 32L, 12L)
    ),
    class = "data.frame",
    row.names = c(NA,-3L)
)

#### Define UI for data upload app ####
ui <- fluidPage(theme = shinytheme("flatly"),
                # set the theme aesthetic

                # App title ----
                tags$h3("demo"),
                # Sidebar layout with input and output definitions ----
                sidebarLayout(
                    sidebarPanel(
                        width = 3,
                        #### conditional panel for surface water QA ######
                        conditionalPanel(
                            condition = "input.conditionedPanels == 1",
                            tags$h4("Load data"),
                            tags$hr(style = "border-color: black;"),
                            fileInput(
                                "file1",
                                "Import file",
                                multiple = FALSE,
                                accept = c("text/csv",
                                           "text/comma-separated-values,text/plain",
                                           ".csv")
                            ),

                            checkboxInput("header", "The dataset has column names", TRUE),
                            radioButtons(
                                "sep",
                                "How are the columns seperated?*",
                                choices = c(
                                    Comma = ",",
                                    Semicolon = ";",
                                    Tab = "\t"
                                ),
                                selected = ",",
                                inline = TRUE
                            ),
                            tags$hr(style = "border-color: black;"),
                            tags$h4("Analysis options"),
                            checkboxInput("show_sw", label = "Show  data", value = TRUE),
                            uiOutput("select_qa_site"),

                            actionButton("run_qa", "Run analysis"),
                            downloadButton("download_qa_sw_table", "Download results")
                        )

                    ),

                    #### Main panel (tabs) for displaying outputs ####
                    mainPanel(
                        useShinyjs(),
                        tabsetPanel(
                            type = "tabs",
                            tabPanel(
                                "QA",
                                br(),
                                tags$h4("Raw data view"),
                                tags$hr(style = "border-color: black;"),
                                dataTableOutput("sw_table"),
                                br(),
                                tags$h4("Analysis view"),
                                tags$hr(style = "border-color: black;"),
                                dataTableOutput("sw_qa_results_table"),
                                value = 1
                            ),
                            id = "conditionedPanels"
                        )

                    )

                ))

server <- function(input, output) 
    #### data input for surface water ####
    data_input <- reactive(
        read.csv(input$file1$datapath,
                 header = input$header,
                 sep = input$sep)
    )

    #### sample site names to choose from and run QA analysis ####
    sw_site_names <- reactive(
        req(input$file1)
        names_sw_data <- colnames(data_input())
        names_sw_data[!(colnames(data_input()) %in% c("site",
                                                      "analyte",
                                                      "QA"))]
    )

    output$select_qa_site <- renderUI(
        # Selecting site names based on variable in uploaded data
        selectInput(
            "Select_site",
            label = h4("Select QA sample site"),
            choices = sw_site_names(),
            selected = NULL
        )
    )


    #### produce data table for raw data inspection  ####
    output$sw_table <- renderDataTable(
        req(input$file1)
        datatable(
            data_input(),
            rownames = FALSE,
            options = list(autoWidth = TRUE, scrollX = TRUE)
        )
    )


    #### show/hide raw data table ####
    observeEvent(input$show_sw, 
        if (input$show_sw)
            show("sw_table")
        else
            hide("sw_table")
    )

    #### run analysis based on user input ####
    qa_table <- eventReactive(input$run_qa, 
        data_input() %>%
            gather(sample_location,
                   value,-c(site, analyte, QA)) %>%
            mutate(
                absolute_diff = abs(value - QA),
                value_mean = (value + QA) / 2,
                RPD = round((absolute_diff / value) * 100, 2)
            ) %>%
            filter() # I would like to filter this data based on input from user #
    )

    #### render results of QA analysis to a table for inspection before downloading ####
    output$sw_qa_results_table <- renderDataTable(
        req(input$file1)
        datatable(
            qa_table(),
            rownames = FALSE,
            options = list(autoWidth = FALSE, scrollX = TRUE)
        )
    )



##### Create Shiny app ####
shinyApp(ui, server)

我也可能只是过度设计了代码,所以我很高兴提出可以实现的建议 相同的结果,但使用不同的方法。

我已经搜索了关于 SO 的解决方案,不认为这是一个重复的问题,但是 如果解决方案已经存在,我很高兴被引导到解决方案。

感谢任何帮助。

【问题讨论】:

欢迎来到***。请将您的库调用添加到代码示例的顶部。否则用户会猜测您正在使用哪些软件包。 @Simon.S.A.对于那个很抱歉。添加到代码顶部。 【参考方案1】:

我相信您想按sample_location 过滤?

你可以通过filter(sample_location == input$Select_site)来做到这一点

所以你的qa_table 将是:

  #### run analysis based on user input ####
  qa_table <- eventReactive(input$run_qa, 
    data_input() %>%
      gather(sample_location,
             value,-c(site, analyte, QA)) %>%
      mutate(
        absolute_diff = abs(value - QA),
        value_mean = (value + QA) / 2,
        RPD = round((absolute_diff / value) * 100, 2)
      ) %>%
      filter(sample_location == input$Select_site) 
  )

【讨论】:

非常感谢。这回答了我的问题。我不知道为什么我在发布之前没有尝试过。

以上是关于根据用户上传数据后选择的用户输入过滤数据框的主要内容,如果未能解决你的问题,请参考以下文章

根据在Flex中文本区域输入的用户输入文本过滤/搜索Array Collection的列表框

根据用户的输入创建列联表 - R Shiny

根据 MS Access 中的用户过滤子表单

如何根据用户表单组合框选择查询单元格中的数据并将数据复制到用户表单文本框中

带组合框的用户表单-输入密钥行为

根据用户选择/输入从集合中过滤对象