在 shiny + DT 中对 data.frame 有反应

reactive to data.frame in shiny + DT

我正在努力处理反应对象。我创建了一个反应函数来改变一个data.frame,但是,我想在反应函数之后计算一些度量。

我目前的工作:

UI代码:

library(shiny)
library(DT)
ui <- fluidPage(
  # App title ----
  titlePanel("CheckList"),
  sidebarLayout(
    
    # Sidebar panel for inputs ----
    sidebarPanel(width = 2,
                 uiOutput("codePanel"), 
                 uiOutput("varPanel") 
    ),
    
    mainPanel(
      
      DT::dataTableOutput("text")
      
    )
  )
)

服务器代码:

server <- function(input, output) {
  
  df <- as.data.frame(cbind(matrix(round(runif(50, -1, 1), 3), 10), sample(0:1, 10, TRUE)))
  
  filt <- selectInput("codeInput",label ="filter1",
                      choices = as.list(unique(df$V6)), multiple = T, selected = 0)
  
  filt2 <- selectInput("varInput",label ="filter2",
                       choices = colnames(df[,-6]), multiple = T, selected = colnames(df[,-6]))
  
  output$codePanel <- renderUI({ filt
    
  })
  
  output$varPanel <- renderUI({ filt2
    
  })
  
  dat <- reactive({
    
    ab <- subset(df, V6 %in% input$codeInput) 
    ab <- ab[,-6]
    ab <- ab[, names(ab) %in% input$varInput] 
    
    
  })
  
 
  
  df1 <- as.data.frame(isolate(dat()))
  
  vals <- reactiveValues()
  vals$rm = mean(rowMeans(df1))
  vals$rr = range(df1)[2]-range(df1)[1]
  vals$r1 = abs(range(df1))[2] - mean(rowMeans(df1))
  vals$r0 = abs(range(df1))[1] - mean(rowMeans(df1))
  
}

我的问题是尝试 isolate(dat() 并将其转换为 data.frame on:

  df1 <- as.data.frame(isolate(dat()))

错误消息说“'closure' 类型的对象不可子集化”。

我不知道这个错误的原因(当我 运行 你的代码时我得到了一个不同的错误)但是你的服务器代码有几个问题。

input$codeInputinput$varInput 在应用程序启动时是 NULL,所以你必须使用 req:

  dat <- reactive({
    req(input$codeInput, input$varInput)
    ab <- subset(df, V6 %in% input$codeInput) 
    ab <- ab[,-6]
    ab <- ab[, names(ab) %in% input$varInput] 
  })

您不能在没有反应性上下文的情况下调用 dat(),就像您在编写 df1 <- as.data.frame(dat()) 时所做的那样。您可以定义您的反应值 vals 如下:

  vals <- reactiveValues()
  
  observe({
    vals$rm = mean(rowMeans(dat()))
    vals$rr = range(dat())[2]-range(dat())[1]
    vals$r1 = abs(range(dat()))[2] - mean(rowMeans(dat()))
    vals$r0 = abs(range(dat()))[1] - mean(rowMeans(dat()))
  })

请注意,我使用 observe 因为它是一个反应性上下文,这是必需的。