简体   繁体   English

如何在R Shiny中选择必须满足多重条件的矩阵行

[英]How to select rows of a matrix which has to meet mutiple conditions in R Shiny

The goal is to build an application able to select and present only rows of a matrix that meets specific conditions selected by the user via Shiny elements such as checkboxes and sliderInput Our data is subject to two (or more) ways to be filtered: 目标是构建一个应用程序,该应用程序只能选择和显示满足用户通过诸如checkboxessliderInput类的Shiny元素选择的特定条件的矩阵行。我们的data受两种(或更多)过滤方式的约束:

  1. Via checkboxGroupInput where user can select one or more numbers 通过checkboxGroupInput ,用户可以选择一个或多个数字
  2. Via sliders . 通过sliders There will be one slider for each column of data . 每一列data都有一个滑块。 This allows user to select the range of numbers for each column. 这允许用户为每一列选择数字范围。

I got stuck on making the data react to the selection entered by the user. 我坚持让data对用户输入的选择做出反应。 Any suggestion is appreciated! 任何建议表示赞赏!

Here is the code that I have: 这是我的代码:

server.R 服务器

   # Load libraries.
   library(shiny)
   library(datasets)
   library(xtable)
   library(R.utils)

 shinyServer(
     function(input, output) {
      source('global.R', local=TRUE)

getDataName <- reactive({
  out <- input$dataName
  print(out)
  return(out)
})

getData <- reactive({
    cat("Getting data for, ", getDataName(), ".", sep = '')
  if(getDataName() == ""){
      print("ERROR: getDAtaName is empty! Check your code!")
      out <- NULL
  }
  else {
      dataSet <- t(combn(max(selectRange(getDataName())), numCols(getDataName())))

  }
  print(head(dataSet, n = 10))
  return(dataSet)
})


selectedValues <- reactive({
  print("Numbers selected via checkboxes:")
  print(input$numSelector)
})      

output$numSelector <- renderUI({
  out <- checkboxGroupInput(
    inputId = "numSelector",
    label   = "Select the numbers to be included in the rows",
    choices = selectRange(input$dataName),  
    inline = TRUE
  )
  return(out)
})

output$sliders <- renderUI({
  numSliders <- numCols(input$dataName)
  lapply(1:numSliders, function(i) {
    sliderInput(
      inputId = paste0('column', i),
      label = paste0('Select the range for column ', i),
      min = min(selectRange(input$dataName)),
      max = max(selectRange(input$dataName)),
      value = c(min(selectRange(input$dataName)), max(selectRange(input$dataName))),
      step =1)
  })
})



output$selectedDataDisplay <- renderDataTable({
  as.table(getData())}, options = list(lengthMenu = c(5, 30, 50), pageLength = 10))
}

)

ui.R 用户界面

library(shiny)

 shinyUI(
    pageWithSidebar(
       headerPanel("Selection zone"),

# Select inputs
sidebarPanel(

  selectInput(
    inputId = "dataName",
    label   = "Select data",
    choices = c("data1", "data2", "data3", "data4")
  ),


  uiOutput(outputId = "numSelector"),
  uiOutput(outputId = "sliders")

),

mainPanel(
   tableOutput("selectedDataDisplay"))

 )
)

global.R 全球

 selectRange <- function(x){
 if(x == "data1"){choices = c(1:10)}
 if(x == "data2"){choices = c(1:15)}
 if(x == "data3"){choices = c(1:20)}
 if(x == "data4"){choices = c(1:25)}
 return(choices)
}

numCols <- function(x){
 if(x == "data1"){maxNum = 10
               numCol = 5}
 if(x == "data2"){maxNum = 15
               numCol = 5}
 if(x == "data3"){maxNum = 20 
              numCol = 5}
 if(x == "data4"){maxNum = 25 
              numCol = 6}
 return(numCol)
 }

You did not provide your actual data sets, so I simulated a couple, and I don't have your exact formulas but hopefully you can extend the idea: 您没有提供实际的数据集,所以我模拟了一些,但我没有确切的公式,但希望您可以扩展一下思路:

ui.R 用户界面

shinyUI(
  pageWithSidebar(
    headerPanel("Selection zone"),

    # Select inputs
    sidebarPanel(

      # User enters name of dat.frame here.
      selectInput(
        inputId = "dataName",
        label   = "Select your data",
        choices = c("data1", "data2", "data3", "data4")
      ),


      uiOutput(outputId = "numSelector"),
      uiOutput(outputId = "sliders")

    ),

    mainPanel(
      tabsetPanel(
        tabPanel("Model Summary", dataTableOutput("selectedDataDisplay"), textOutput("vars"))

      )
    )
  ))

server.R 服务器

library(shiny)
library(data.table)

data1 <- matrix(round(runif(10000, min = 1, max = 20), 0), ncol = 10)
data2 <- matrix(round(runif(10000, min = 1, max = 20), 0), ncol = 10)
data3 <- matrix(round(runif(10000, min = 1, max = 20), 0), ncol = 10)
data4 <- matrix(round(runif(10000, min = 1, max = 20), 0), ncol = 10)

shinyServer(function(input, output) {

  output$numSelector <- renderUI({
    out <- checkboxGroupInput(
      inputId = "numSelector",
      label   = "Select the numbers to be included in the rows",
      choices = 1:20,  
      inline = TRUE
    )
    return(out)
  })


  output$sliders <- renderUI({
    numSliders <- eval(parse(text = c("ncol(",input$dataName, ")")))
    lapply(1:numSliders, function(i) {
      sliderInput(
        inputId = paste0('column', i),
        label = paste0('Select the range for column ', i),
        min = 1,
        max = 20,
        value = c(1, 20),
        step = 1)
    })
  })

  dataSet <- reactive({
    if ( is.null(input$column1) ){

    } else {
      colName <- "Column"
      eval(parse(text = c(paste0("set <- as.data.table(", input$dataName, ")"))))
      setnames(set, colnames(set), paste0(colName, seq(ncol(set))))

      # generate boolean values for each column's rows based upon individual ranges & the over all 
      validRows <- list()
      for(k in seq(ncol(set))){
        validRows[[k]] <- eval(parse(text = paste0("with(set, ", colName, k, " %in% input$column", k, "[1]:input$column", k, "[2] &  ", colName, k, " %in% input$numSelector )")))
      }

      validRows <- do.call(cbind, validRows)

      # if any of the column's conditions are satisfied, the row is accepted
      validRows <- apply(validRows, 1, any)

      # ouput accepted rows
      set[ validRows ]  
    }
  })

  output$selectedDataDisplay <- renderDataTable(dataSet(), options = list(lengthMenu = c(5, 30, 50), pageLength = 10))

})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM