【问题标题】:Subset a dataframe based on dynamic number and names of columns根据动态列数和名称对数据框进行子集化
【发布时间】:2020-09-07 22:52:02
【问题描述】:

我有下面的闪亮应用程序,用户可以在其中从数据框中选择一个或多个列名。

name<-c("John","Jack","Bill")
value1<-c(2,4,6)
add<-c("SDF","GHK","FGH")
value2<-c(3,4,5)
dt<-data.frame(name,value1,add,value2)

那么对于他所做的每一个选择,相对的pickerInput() 可能会显示在下面。然后根据选择的列或列及其值,我想对初始数据框进行子集化并将其显示在表格中。但是对于我将在原始应用程序中使用的每个不同的数据框,列的名称可能会有所不同,因此我不知道如何对其进行子集化。

library(DT)
# ui object
ui <- fluidPage(
    titlePanel(p("Spatial app", style = "color:#3474A7")),
    sidebarLayout(
        sidebarPanel(
            pickerInput(
                inputId = "p1",
                label = "Select Column headers",
                choices = colnames( dt),
                multiple = TRUE,
                options = list(`actions-box` = TRUE)
            ),
            #Add the output for new pickers
            uiOutput("pickers")
        ),
        
        mainPanel(
            DTOutput("table")
        )
    )
)

# server()
server <- function(input, output) {
    
    observeEvent(input$p1, {
        #Create the new pickers 
        output$pickers<-renderUI({
            div(lapply(input$p1, function(x){
                if (is.numeric(dt[[x]])) {
                    sliderInput(inputId=x, label=x, min=min(dt[x]), max=max(dt[[x]]), value=c(min(dt[[x]]),max(dt[[x]])))
                }
                else if (is.factor(dt[[x]])) {
                    selectInput(
                        inputId = x#The colname of selected column
                        ,
                        label = x #The colname of selected column
                        ,
                        choices = dt[,x]#all rows of selected column
                        ,
                        multiple = TRUE
                        
                    )
                }
                
            }))
        })
    })
    output$table<-renderDT({
        req(input$p1, sapply(input$p1, function(x) input[[x]]))
        dt_part <- dt
        for (colname in input$p1) {
            dt_part <- subset(dt_part, dt_part[[colname]] %in% input[[colname]])
        }
        dt_part
    })
}

# shinyApp()
shinyApp(ui = ui, server = server)

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    如果您将output$table 更改为以下内容,则可以:

    output$table<-renderDT({
      req(input$p1, sapply(input$p1, function(x) input[[x]]))
      dt_part <- dt
      for (colname in input$p1) {
          if (is.factor(dt_part[[colname]])) {
            dt_part <- subset(dt_part, dt_part[[colname]] %in% input[[colname]])
          } else {
            dt_part <- subset(dt_part, (dt_part[[colname]] >= input[[colname]][[1]]) & dt_part[[colname]] <= input[[colname]][[2]])
          }
      }
      dt_part
    })
    

    第一行确保必填字段可用。
    其余行根据input$p1 中的列和input[[input$p1]] 中的值重复过滤dt

    【讨论】:

    • 我认为部分可行。假设我选择 name 和 value1 作为子集。在从名称中选择之前,我应该已经拥有表中的所有名称,因为滑块范围涵盖了所有值。另外,如果我从 value1 中选择所有名称和所有值,则 Jack 丢失
    • 我编辑了我的答案以检查该值是否在滑块的范围内,而不是检查它是否是端点之一(这是之前发生的)。我注意到您编辑了您的问题以纳入我的答案。我认为这样做是不明智的,因为这会混淆您最初的问题,并使其他人难以使用它。
    • 对此很抱歉,但在没有滑块的情况下也会发生这种情况,但你说得对,我忘了提。现在看起来更好了,但如果我选择名称(没有选择任何名称)和选择了所有值的 value1,我会得到一个空表,而我应该拥有所有值。当我开始时,表开始被填满选择名称
    • 我会给你这个答案,因为它回答了原来的 Q 并用新问题创建了一个新问题。 stackoverflow.com/questions/63779991/…
    猜你喜欢
    • 2013-08-15
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    • 2013-04-22
    • 2011-08-13
    相关资源
    最近更新 更多