闪亮:动态数据框构造; renderUI,观察,reactiveValues [英] Shiny: dynamic dataframe construction; renderUI, observe, reactiveValues

查看:87
本文介绍了闪亮:动态数据框构造; renderUI,观察,reactiveValues的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为如何经常使用Shiny的renderUI功能动态子集数据的问题经常出现,但是我很难理解何时将renderUI(与uiOutput一起使用)与其他功能(包括观察,反应式,reactiveValues甚至conditionalPanel)一起使用。

i think the question of how to dynamically subset data using Shiny's renderUI functionality comes up every so often but i'm struggling to understand when to use renderUI (with uiOutput) over other functionality including observe, reactive, reactiveValues and even conditionalPanel.

我想构建一个完全交互式的数据框,其中每个选择都会影响您在其他输入中可以选择的内容。在此示例中,我们将有一个selectInput(单个),selectInput(多个)和一个sliderInput(具有max& min)。

I would like to build a fully interactive dataframe in which every choice influences what you can choose in the other inputs. For this example we will have a selectInput (single), selectInput (multi) and a sliderInput (with max & min).

主选择类别1可以是类别1中的任何值或全部。通过在类别1中选择某些内容,您又会影响可以在类别2中显示的内容以及滑块上的值范围。通过首先选择类别2,可以限制类别1的选项以及滑块中的值(它们始终代表子集的最大值和最小值)。通过从sliderInput开始,如果类别1和类别2的数据均不在您指定的范围内,则它们将受到限制。

The primary select, Category 1, can be any value in Category 1 or "All". By selecting something in Category 1, you in turn influence what can be shown in Category 2 and the range of values on the slider. By choosing Category 2 first, you restrict the options of Category 1 and also the values in the slider (which always represent the max and min of the subset). By starting with the sliderInput, Category 1 and Category 2 are limited if none of their data fall in the range you have stated.

N.B。我将合并一个重置 actionButton以将数据帧重置为应用程序初始化时的状态。

N.B. i will incorporate a 'reset' actionButton to reset the dataframe to what it is when the app initialises.

尝试使用一些虚拟数据,但我没有设法得到加工。这将按类别1进行子集并更新滑块,但更改类别2不会覆盖呈现的表;

an attempt using some dummy data, which I have not managed to get working. This will subset by Category 1 and update the slider but changing Category 2 will not overwrite the rendered table;

require(shiny)

    data <- data.frame(Category1 = rep(letters[1:3],each=15),
                       Info = paste("Text info",1:45),
                       Category2 = sample(letters[15:20],45,replace=T),
                       Size = sample(1:100, 45),
                       MoreStuff = paste("More Stuff",1:45))

ui <- fluidPage(

  titlePanel("Test Explorer"),

  sidebarLayout(
    sidebarPanel(
      uiOutput("category1"),
      uiOutput("category2"),
      uiOutput("sizeslider")
      ),
    mainPanel(
      tableOutput("table")
    )
  )
)

server <- function(input, output,session) {

  df_subset <- reactive({
    if(input$cat1=="All") {df_subset <- data}
    else{df_subset <- data[data$Category1==input$cat1,]}

  })

  df_subset1 <- reactive({
    if(is.null(input$cat2)){df_subset()} else {df_subset()[df_subset()$Category2==input$cat2,]}
  })

  output$category1 <- renderUI({
    selectizeInput('cat1', 'Choose Cat 1', choices = c("All",sort(as.character(unique(data$Category1)))),selected = "All")
  })

  output$category2 <- renderUI({
    selectizeInput('cat2', 'Choose Cat 2 (optional):', choices = sort(as.character(unique(df_subset1()$Category2))), multiple = TRUE,options=NULL)
  })

  output$sizeslider <- renderUI({
    sliderInput("size", label = "Size Range", min=min(df_subset1()$Size), max=max(df_subset1()$Size), value = c(min(df_subset1()$Size),max(df_subset1()$Size)))
  })

  output$table <- renderTable({
    df_subset1()
  })

}

shinyApp(ui, server)


推荐答案

棘手的是要跟踪正在发生的事情,但这是您想要的吗?注意将 reactive 更改为 eventReactive ,因此它专门绑定到输入。我还使用了%in%运算符为 selectizeInput

A bit tricky to follow what is happening, however, is this what you want? Note changed the reactive into eventReactive so it is specifically bound to an input. Also I used the %in% operator to have multiple selects for your selectizeInput

编辑:在您甚至没有使用滑块的第一个代码中,我将其添加到了过滤中

#rm(list = ls())
library(shiny)

data <- data.frame(Category1 = rep(letters[1:3],each=15),
                   Info = paste("Text info",1:45),
                   Category2 = sample(letters[15:20],45,replace=T),
                   Size = sample(1:100, 45),
                   MoreStuff = paste("More Stuff",1:45))

ui <- fluidPage(

  titlePanel("Test Explorer"),
  sidebarLayout(
    sidebarPanel(
      uiOutput("category1"),
      uiOutput("category2"),
      uiOutput("sizeslider")
    ),
    mainPanel(
      tableOutput("table")
    )
  )
)

server <- function(input, output,session) {

  output$category1 <- renderUI({
    selectizeInput('cat1', 'Choose Cat 1', choices = c("All",sort(as.character(unique(data$Category1)))),selected = "All")
  })

  df_subset <- eventReactive(input$cat1,{
    if(input$cat1=="All") {df_subset <- data}
    else{df_subset <- data[data$Category1 == input$cat1,]}
  })

  df_subset1 <- reactive({
    if(is.null(input$cat2)){df_subset()} else {df_subset()[df_subset()$Category2 %in% input$cat2,]}
  })

  output$category2 <- renderUI({
    selectizeInput('cat2', 'Choose Cat 2 (optional):', choices = sort(as.character(unique(df_subset()$Category2))), multiple = TRUE,options=NULL)
  })

  output$sizeslider <- renderUI({
    sliderInput("size", label = "Size Range", min=min(df_subset1()$Size), max=max(df_subset1()$Size), value = c(min(df_subset1()$Size),max(df_subset1()$Size)))
  })

  df_subset2 <- reactive({
    if(is.null(input$size)){df_subset1()} else {df_subset1()[df_subset1()$Size >= input$size[1] & df_subset1()$Size <= input$size[2],]}
  })

  output$table <- renderTable({
    df_subset2()
  })
}

shinyApp(ui, server)

这篇关于闪亮:动态数据框构造; renderUI,观察,reactiveValues的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆