代码之家  ›  专栏  ›  技术社区  ›  dan

在R Shining应用程序中美观地显示要从中子集的长数据帧

  •  0
  • dan  · 技术社区  · 5 年前

    我有一些数据( design.df R shiny 应用程序:

    set.seed(1)
    library(dplyr)
    samples <- paste0("s",1:5)
    clusters <- paste0("c",1:10)
    groups <- paste0("g",1:20)
    
    design.df <- expand.grid(samples,clusters,groups) %>%
        dplyr::rename(sample=Var1,cluster=Var2,group=Var3) %>%
        dplyr::mutate(value=rnorm(nrow(.)))
    

    我希望允许用户能够将 通过任何列(保留 value sample , cluster group ,但实际上,这是一个不同用户将加载到的应用程序 data.frame 具有不同列的(保留 价值 列)。

    我正在努力适应 10.3.2 Dynamic filtering

    这是我的代码:

    library(shiny)
    library(dplyr)
    
    make_ui <- function(x, var) {
      if (is.numeric(x)) {
        rng <- range(x, na.rm = TRUE)
        sliderInput(var, var, min = rng[1], max = rng[2], value = rng)
      } else if (is.factor(x)) {
        levs <- levels(x)
        selectInput(var, var, choices = levs, selected = levs, multiple = TRUE)
      } else {
        # Not supported
        NULL
      }
    }
    
    filter_var <- function(x, val) {
      if (is.numeric(x)) {
        !is.na(x) & x >= val[1] & x <= val[2]
      } else if (is.factor(x)) {
        x %in% val
      } else {
        # No control, so don't filter
        TRUE
      }
    }
    
    server <- function(input, output)
    {
      data <- reactive({
        get(input$dataset, data.frame(dplyr::select(design.df,-value)))
      })
      
      vars <- reactive(names(data()))
      
      output$filter <- renderUI(
        purrr::map(vars, ~ make_ui(data()[[.x]], .x))
      )
      
      selected <- reactive({
        each_var <- purrr::map(vars, ~ filter_var(data()[[.x]], input[[.x]]))
        purrr::reduce(each_var, `&`)
      })
      
      scatter.plot <- reactive({
        scatter.plot <- NULL
        if(!is.null(data()[selected(),]){
          plot.df <- suppressWarnings(data()[selected(), ])
          scatter.plot <- suppressWarnings(plotly::plot_ly(marker=list(size=3),type='scatter',mode="markers",color=plot.df$sample,x=plot.df$group,y=plot.df$value) %>%
                                             plotly::layout(xaxis=list(title="group",showgrid=F),yaxis=list(title="value",showgrid=F)))
        }
        return(scatter.plot)
      })
        
      output$out.plot <- plotly::renderPlotly({
        scatter.plot()
      })  
    }
    
    ui <- fluidPage(
      titlePanel("Data Explorer"),
      sidebarLayout(
        sidebarPanel(
          tags$head(
            tags$style(HTML(".multicol {-webkit-column-count: 3; /* Chrome, Safari, Opera */-moz-column-count: 3; /* Firefox */column-count: 3;}")),
            tags$style(type="text/css", "#loadmessage {position: fixed;top: 0px;left: 0px;width: 100%;padding: 5px 0px 5px 0px;text-align: center;font-weight: bold;font-size: 100%;color: #000000;background-color: #CCFF66;z-index: 105;}"),
            tags$style(type="text/css",".shiny-output-error { visibility: hidden; }",".shiny-output-error:before { visibility: hidden; }")),
          conditionalPanel(condition="$('html').hasClass('shiny-busy')",tags$div("In Progress...",id="loadmessage")),
          selectInput("dataset", label = "Dataset", choices = colnames(dplyr::select(design.df,-value))),
          uiOutput("filter"),
        ),
        mainPanel(
          plotly::plotlyOutput("out.plot")
        )
      )
    )
    
    shinyApp(ui = ui, server = server)
    

    这提供了该接口: enter image description here

    它接近我想要的,但仍有一些问题:

    1. 它没有显示散点图,可能是因为我在 scatter.plot reactive .

    解决这些问题后,我还需要更新 反应性 因此它不会显式地从设计中选择列名。df,而是经过挑选的,但这对这篇文章来说一点都不重要。

    0 回复  |  直到 5 年前
        1
  •  1
  •   dan    5 年前

    数据:

    set.seed(1)
    library(dplyr)
    samples <- paste0("s",1:5)
    clusters <- paste0("c",1:10)
    groups <- paste0("g",1:20)
    
    design.df <- expand.grid(samples,clusters,groups) %>%
        dplyr::rename(sample=Var1,cluster=Var2,group=Var3) %>%
        dplyr::mutate(value=rnorm(nrow(.)))
    

    library(shiny)
    library(dplyr)
    
    make_ui <- function(x, var) {
      if (is.numeric(x)) {
        rng <- range(x, na.rm = TRUE)
        sliderInput(var, var, min = rng[1], max = rng[2], value = rng)
      } else if (is.factor(x)) {
        levs <- levels(x)
        selectInput(var, var, choices = levs, selected = levs, multiple = TRUE)
      } else {
        # Not supported
        NULL
      }
    }
    
    filter_var <- function(x, val) {
      if (is.numeric(x)) {
        !is.na(x) & x >= val[1] & x <= val[2]
      } else if (is.factor(x)) {
        x %in% val
      } else {
        # No control, so don't filter
        TRUE
      }
    }
    
    server <- function(input, output)
    {
      output$filter <- renderUI(
        purrr::map(colnames(data.frame(dplyr::select(design.df,-value))), ~ make_ui(data.frame(dplyr::select(design.df,-value))[[.x]], .x))
      )
      
      selected <- reactive({
        each_var <- purrr::map(colnames(data.frame(dplyr::select(design.df,-value))), ~ filter_var(data.frame(dplyr::select(design.df,-value))[[.x]], input[[.x]]))
        purrr::reduce(each_var, `&`)
      })
      
      scatter.plot <- reactive({
        scatter.plot <- NULL
        if(!is.null(data.frame(dplyr::select(design.df,-value))[selected(),])){
          plot.df <- suppressWarnings(data.frame(dplyr::select(design.df,-value))[selected(), ])
          scatter.plot <- suppressWarnings(plotly::plot_ly(marker=list(size=3),type='scatter',mode="markers",color=plot.df$sample,x=plot.df$group,y=plot.df$value) %>%
                                           plotly::layout(xaxis=list(title="group",showgrid=F),yaxis=list(title="value",showgrid=F)))
        }
        return(scatter.plot)
      })
        
      output$out.plot <- plotly::renderPlotly({
        scatter.plot()
      })  
    }
    
    ui <- fluidPage(
      titlePanel("Data Explorer"),
      sidebarLayout(
        sidebarPanel(
          tags$head(
            tags$style(HTML(".multicol {-webkit-column-count: 3; /* Chrome, Safari, Opera */-moz-column-count: 3; /* Firefox */column-count: 3;}")),
            tags$style(type="text/css", "#loadmessage {position: fixed;top: 0px;left: 0px;width: 100%;padding: 5px 0px 5px 0px;text-align: center;font-weight: bold;font-size: 100%;color: #000000;background-color: #CCFF66;z-index: 105;}"),
            tags$style(type="text/css",".shiny-output-error { visibility: hidden; }",".shiny-output-error:before { visibility: hidden; }")),
          conditionalPanel(condition="$('html').hasClass('shiny-busy')",tags$div("In Progress...",id="loadmessage")),
          uiOutput("filter"),
        ),
        mainPanel(
          plotly::plotlyOutput("out.plot")
        )
      )
    )
    
    shinyApp(ui = ui, server = server)
    

    其中给出: enter image description here