我想知道一种有效的方法来做到以下几点。在闪亮的应用程序中有一个反应性dataframe()
。我希望有两个无功输入(每个有两种可能性TRUE
或FALSE
),它们分别根据两列中的值对行进行子集化。如果我只有一个输入(和一列photos
),我会这样做:
df<-reactive({
df<-mydf
if(input$myinput==FALSE)
{
df<-df[!df$photos=="",]
}
else{
df
}
})
问题是如果我有两个(或更多)输入(和列),如果我在示例中的if
和else
内使用嵌套的if
和else
,则代码将增长太多,以允许两个TRUE/FALSE
输入的4种可能性。
编辑:可重复,使第二次输入工作没有太多if
和else
:
server <- function(input, output, session) {
df<-reactive({
df<-iris
if(input$Petalw==T)
{
df<-df[df$Petal.Width==0.2,]
}
else{
df
}
})
output$table <- DT::renderDataTable(
DT::datatable(df(), options = list(searching = FALSE,pageLength = 25))
)
}
ui <- navbarPage(
title = 'Select values in two columns based on two inputs respectively',
fluidRow(
column(width = 3,
checkboxInput("Petalw","PetalWithIs0.2",T),
checkboxInput("PetalL","PetalLengthis1.4",T)
),
column(9,
tabPanel('Table', DT::dataTableOutput('table'))
)
)
)
shinyApp(ui, server)
您可以通过input[[inputName]]
访问输入,其中inputName是输入的名称(例如“Sepal.Length-7.9”)。然后你可以通过检查所有输入
if(input[[inputName]]){
split <- strsplit(inputName, "-")[[1]]
name <- split[1]
treshold <- as.numeric(split[2])
global$filter[, inputName ==colnames(filter)] <- iris[name] == treshold
}else{
global$filter[, inputName ==colnames(filter)] = TRUE
}
您可以使用renderUI()
创建的输入:
output$checkBoxes <- renderUI({
lapply(inputNames, function(inputName) checkboxInput(inputName, inputName, FALSE))
})
在示例中,我使用所有数值列的最大值。
完整代码如下:
restr <- apply(iris, 2, max)[1:4]
inputNames <- paste(names(restr), restr, sep = "-")
filter = sapply(inputNames, function(inputName) c(inputName = return(rep(TRUE, dim(iris)[1]))))
server <- function(input, output, session) {
global <- reactiveValues(filter = filter)
df <- reactive({
for(inputName in inputNames){
if(!is.null(input[[inputName]])){
isolate({
if(input[[inputName]]){
split <- strsplit(inputName, "-")[[1]]
name <- split[1]
treshold <- as.numeric(split[2])
global$filter[, inputName ==colnames(filter)] <- iris[name] == treshold
}else{
global$filter[, inputName ==colnames(filter)] = TRUE
}
})
}
}
iris[rowSums(global$filter) == 4, ]
})
output$checkBoxes <- renderUI({
lapply(inputNames, function(inputName) checkboxInput(inputName, inputName, FALSE))
})
output$table <- DT::renderDataTable(
DT::datatable(df(), options = list(searching = FALSE,pageLength = 25))
)
}
ui <- navbarPage(
title = 'Select values in two columns based on two inputs respectively',
fluidRow(
column(width = 3,
uiOutput("checkBoxes")
),
column(9,
tabPanel('Table', DT::dataTableOutput('table'))
)
)
)
shinyApp(ui, server)
您可以让用户为一列选择一个值,根据该值对数据进行子集化,然后使用renderUI
并使用其他列的值生成动态selectInput
下拉列表。
server <- function(input, output, session) {
df <- reactive({
subset(iris, Petal.Width == input$Petalw)
})
# Extract list of Petal Lengths from selected data - to be used as a filter
p.lengths <- reactive({
unique(df()$Petal.Length)
})
# Filter based on Petal Length
output$PetalL <- renderUI({
selectInput("PetalLengthSelector", "PetalLength", as.list(p.lengths()))
})
# Subset this data based on the values selected by user
df_1 <- reactive({
foo <- subset(df(), Petal.Length == input$PetalLengthSelector)
return(foo)
})
output$table <- DT::renderDataTable(
DT::datatable(df_1(), options = list(searching = FALSE,pageLength = 25))
)
}
ui <- navbarPage(
title = 'Select values in two columns based on two inputs respectively',
fluidRow(
column(width = 3,
selectInput("Petalw","PetalWidth", choices = unique(iris$Petal.Width)),
uiOutput("PetalL")
),
column(9,
tabPanel('Table', DT::dataTableOutput('table'))
)
)
)
shinyApp(ui, server)