在 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$codeInput
和 input$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
因为它是一个反应性上下文,这是必需的。
我正在努力处理反应对象。我创建了一个反应函数来改变一个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$codeInput
和 input$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
因为它是一个反应性上下文,这是必需的。