R Shiny 如何为 Dataframe 创建从属过滤器

如何解决R Shiny 如何为 Dataframe 创建从属过滤器

我需要创建一个应用程序,在其中过滤数据框中的多个字段。当第一个字段被过滤(使用日期范围)时,用户必须在数据显示在表格中之前过滤几个选择器输入。我不确定这是否是创建相关过滤器的最佳方式。我似乎找不到足够的资源。我尝试了以下方法。但是,我不确定为什么我不断收到此警告::

警告:错误:filter() 输入“..1”有问题 X 输入 '..1' 的大小必须是 100 或 1,而不是大小 0

get_data <- function(size){
  longs <- seq(from=40,to =90,by = 0.01)
  lats <- seq(from = 5,to= 50,by = 0.01)
  LONGITUDE <- sample(longs,size,rep = TRUE)
  LATITUDE <- sample(lats,rep = TRUE)
  df <- data.frame(cbind(LONGITUDE,LATITUDE))
  df$LOCATION <- sample(c("Location_A","Location_B","Location_C"),replace = T,prob = c(0.4,0.4,0.2))
  df$EQUIPMENT <- sample(c("Equipment_A","Equipment_B","Equipment_C","Equipment_D"),replace = TRUE)
  startTime <- as.POSIXct("2016-01-01")
  endTime <- as.POSIXct("2019-01-31")
  df$DATE <- as.Date(sample(seq(startTime,endTime,1),size))
  df$WEEKDAY <- weekdays(as.Date(df$DATE))
  
  return(df)
}

df <-get_data(100)

ui <- navbarPage(
  id = "navBar",title = "Data Exploration",theme = shinytheme("cerulean"),shinyjs::useShinyjs(),selected = "Data",tabPanel("Data",fluidPage(
             sidebarPanel(
               
               
               div(id = "form",uIoUtput('timestamp'),uIoUtput('location'),uIoUtput('days_of_week'),uIoUtput('equipment_type'),hr(),HTML("<h3>Reset your filter settings here:</h3>"),actionButton("resetAll","Reset Entries"),hr()),mainPanel(
                 DT::DTOutput("datatable"))))
  )
  
)#end the ui


server <- function(session,input,output){
  filter_data <- reactive({
    df %>%
      filter(DATE >= input$timestamp[1] & DATE <= input$timestamp[2]) %>%
      filter(LOCATION %in% input$location) %>%
      filter(WEEKDAY %in% input$days_of_week) %>%
      filter(EQUIPMENT %in% input$equipment_type)
  })
  
  output$timestamp <- renderUI({
    daterangeInput('timestamp',label = 'Date range input:',start = min(df$DATE),end = max(df$DATE))
  })
  
  output$location <- renderUI({
    location <- reactive({
      df %>%
        filter(DATE >= input$timestamp[1] & DATE <= input$timestamp[2]) %>%
        pull(LOCATION) %>%
        as.character() %>% unique()
      
    })
    pickerInput('location',"Select Location:",choices = location(),selected = NULL,options = list(`actions-Box` = TRUE),multiple = T)
  })
  
  output$days_of_week <- renderUI({
    days_of_week <- reactive({
      df %>%
        filter(DATE >= input$timestamp[1] & DATE <= input$timestamp[2]) %>%
        filter(LOCATION %in% input$location) %>%
        pull(WEEKDAY) %>%
        as.character() %>% unique()
      
    })
    pickerInput('days_of_week','Choose Weekdays:',choices=days_of_week(),multiple = T)
  })
  
  output$equipment_type <- renderUI({
    equipment <- reactive({
      df %>%
        filter(DATE >= input$timestamp[1] & DATE <= input$timestamp[2]) %>%
        filter(LOCATION%in% input$location) %>%
        filter(WEEKDAY %in% input$days_of_week) %>%
        pull(EQUIPMENT) %>%
        as.character() %>% unique()
    })
    pickerInput('equipment_type',"Choose Equipment:",choices = equipment(),multiple = T)
  })
  
  output$datatable <- DT::renderDT({
    filter_data()
  })
  
  #Allow the user to reset all their inputs
  observeEvent(input$resetAll,{
    reset("form")
  })
  
}

shinyApp(ui,server)

解决方法

我认为您的警告是由于 input$timestamp 在您创建 dateRangeInput 之前第一次在您的反应式表达式中为 NULL。

您可以将 input 移动到 ui,然后在日期更改时使用 updatePickerInput 以相应地更改您的其他输入。

您可能想要包含两个单独的 reaction 表达式。一个用于根据日期范围过滤数据,这将用于更新其他选择器。第二个将包括基于选择器选择的位置、设备和工作日的其他过滤器。

看看这是否提供了更接近您正在寻找的东西。我在顶部包含了似乎是相关的包。我还稍微调整了 ui 中的括号。

library(shinythemes)
library(shinyWidgets)
library(shinyjs)
library(shiny)
library(dplyr)

get_data <- function(size){
  longs <- seq(from=40,to =90,by = 0.01)
  lats <- seq(from = 5,to= 50,by = 0.01)
  LONGITUDE <- sample(longs,size,rep = TRUE)
  LATITUDE <- sample(lats,rep = TRUE)
  df <- data.frame(cbind(LONGITUDE,LATITUDE))
  df$LOCATION <- sample(c("Location_A","Location_B","Location_C"),replace = T,prob = c(0.4,0.4,0.2))
  df$EQUIPMENT <- sample(c("Equipment_A","Equipment_B","Equipment_C","Equipment_D"),replace = TRUE)
  startTime <- as.POSIXct("2016-01-01")
  endTime <- as.POSIXct("2019-01-31")
  df$DATE <- as.Date(sample(seq(startTime,endTime,1),size))
  df$WEEKDAY <- weekdays(as.Date(df$DATE))
  
  return(df)
}

df <-get_data(100)

ui <- navbarPage(
  id = "navBar",title = "Data Exploration",theme = shinytheme("cerulean"),shinyjs::useShinyjs(),selected = "Data",tabPanel("Data",fluidPage(
             sidebarPanel(
               div(id = "form",dateRangeInput('timestamp',label = 'Date range input:',start = min(df$DATE),end = max(df$DATE)),pickerInput('location',"Select Location:",choices = unique(df$LOCATION),options = list(`actions-box` = TRUE),multiple = T),pickerInput('days_of_week','Choose Weekdays:',choices = unique(df$WEEKDAY),pickerInput('equipment_type',"Choose Equipment:",choices = unique(df$EQUIPMENT),hr(),HTML("<h3>Reset your filter settings here:</h3>"),actionButton("resetAll","Reset Entries"),hr())
               ),mainPanel(
                 DT::DTOutput("datatable")))
  )
)#end the ui

server <- function(session,input,output){
  
  filter_by_dates <- reactive({
    filter(df,DATE >= input$timestamp[1] & DATE <= input$timestamp[2])
  })
  
  filter_by_all <- reactive({
    fd <- filter_by_dates()
    
    if (!is.null(input$location)) {
      fd <- filter(fd,LOCATION %in% input$location)
    }
    
    if (!is.null(input$days_of_week)) {
      fd <- filter(fd,WEEKDAY %in% input$days_of_week)
    }
    
    if (!is.null(input$equipment_type)) {
      fd <- filter(fd,EQUIPMENT %in% input$equipment_type)
    }         
             
    return(fd)
  })
  
  observeEvent(input$timestamp,{
    updatePickerInput(session,'location',choices = unique(filter_by_dates()$LOCATION),selected = input$location)
    updatePickerInput(session,'days_of_week',choices = unique(filter_by_dates()$WEEKDAY),selected = input$days_of_week)
    updatePickerInput(session,'equipment_type',choices = unique(filter_by_dates()$EQUIPMENT),selected = input$equipment_type)
  })
  
  output$datatable <- DT::renderDT({
    filter_by_all()
  })
  
  #Allow the user to reset all their inputs
  observeEvent(input$resetAll,{
    reset("form")
  })
  
}

shinyApp(ui,server)

编辑 (1/28/21):根据评论,似乎有兴趣根据所做的选择更新所有输入选项。

如果将 observeEvent 替换为 observe,并在三个 filter_by_all() 中使用 filter_by_date() 代替 updatePickerInput,则所有非日期输入选项每当对任何输入进行任何更改时都会更新:

  observe({
    input$timestamp
    updatePickerInput(session,choices = unique(filter_by_all()$LOCATION),choices = unique(filter_by_all()$WEEKDAY),choices = unique(filter_by_all()$EQUIPMENT),selected = input$equipment_type)
  })

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?