当输入为空时,在闪亮的应用程序中没有data.frame的子集,如果没有多个if语句,如何做到这一点?

时间:2017-02-11 21:13:30

标签: r shiny

我根据用户可以指定的各种输入在闪亮的应用程序中对数据框进行子集化。如果输入字段为空,则不应进行子集化。我可以在

的反应声明中实现这一点
data_subset <- reactive({
  if (!is.null(input$input_a)) {data <- subset(data, a %in% input$input_a}
  # lots of similar if statements for inputs b, c, d ...
  data
})

我有很多这些if语句检查输入是否为NULL。但是,有超过10或20个这样的语句一个接一个,代码看起来有点混乱和冗长。

有更好的方法吗?也许req可以帮忙吗?

2 个答案:

答案 0 :(得分:2)

您应该能够调整此代码以满足您的需求。 Reduce是一个列表,其中包含您用于子集的不同元素。您可以在反应函数中提取所需的函数,然后使用高阶函数# Setup example input <- list(input_vs = NULL, input_am = 1, input_gear = 4) # Inputs coming from ui data <- mtcars # Data # In the reactive expression inpt <- reactiveValuesToList(input) indx <- inpt[grepl("input", names(inpt))] # Extract the inputs you want names(indx) <- gsub("input_", "", names(indx)) # Remove the prefix to get the associated variable names indx <- Filter(Negate(is.null), indx) # Remove the null ones # Find indices indx <- lapply(seq_along(indx), function(i) data[, names(indx)[i]] %in% indx[[i]]) indx <- Reduce(`&`, indx) # Subset data data[indx, ] 来提供逻辑矢量来索引数据。

:last-child

答案 1 :(得分:1)

我只是想出一个使用简单for循环的解决方案。我定义了一个辅助函数来检查输入是否为空,仅当输入不为空时才定义子集。

library(shiny)

data <- iris

# return TRUE if shiny input is empty, e.g. NULL, "", FALSE
is_input_empty <- function(ui_input) {
  if (is.null(ui_input)) return(TRUE)
  if (length(ui_input) != 1) return(FALSE)
  if (ui_input == "") return(TRUE)
  if (ui_input == FALSE) return(TRUE)
  return(FALSE)
}

ui <- fluidPage(
  selectizeInput("Species", "Species", choices = levels(data$Species),
                 multiple = TRUE, selected = c("versicolor", "setosa")),
  plotOutput("plot_iris")
)

server <- function(input, output) {

    data_subset <- reactive({
      input_vars <- "Species"

      # iterate over the inputs, if not NULL subset the data
      for (i in input_vars){
        if (!is_input_empty(input[[i]])) {data <- data[data[, i] %in% input[[i]], ]}
      }
      data
    })

    output$plot_iris <- renderPlot(plot(data_subset()$Sepal.Length, 
                                        data_subset()$Sepal.Width))
}

shinyApp(ui, server)