我根据用户可以指定的各种输入在闪亮的应用程序中对数据框进行子集化。如果输入字段为空,则不应进行子集化。我可以在
的反应声明中实现这一点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可以帮忙吗?
答案 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)