我浪费了几个小时来找出为什么我的绘图在我更改输入时自动更新自己,而它本应该等待运行按钮,但它只是忽略了这一步,我最终发现ggplot是个麻烦制造者!!!这是我的最小代码:
library(ggplot2)
library(tidyverse)
varnames <- names(cars)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fluidRow(
column(
width = 12,
# Variables Inputs:
varSelectInput("variables", "Select Input Variables", cars, multiple = TRUE),
selectizeInput("outvar", "Select Output Variable", choices = varnames, "speed", multiple = F),
# Run Button
actionButton(inputId = "run", label = "Run")
)
)
),
# Main panel for displaying outputs ----
mainPanel(
plotOutput("plot")
)
)
)
server <- function(input, output, session) {
df <- reactive({
cars %>% dplyr::select(!!!input$variables, input$outvar)
})
plt <- eventReactive(input$run, {
#Just creating lm formula
current_formula <- paste0(input$outvar, " ~ ", paste0(input$variables, collapse = " + "))
current_formula <- as.formula(current_formula)
#Fitting lm
fit <- lm(current_formula, data = df())
pred <- predict(fit, newdata = df())
#Plotting
ggplot(df(), aes(df()[, input$outvar], pred)) +
labs(x = "Observed", y = "Predicted") +
geom_point() +
theme_bw()
#plot(df()[, input$outvar], pred) #This one works fine!!!!
})
output$plot <- renderPlot({
plt()
})
}
# Run the application
shinyApp(ui = ui, server = server)
如果你运行这个,你会注意到,在第一次运行后,ggplod不再关心运行按钮,它会在你更改输入时不断更新!!然而,如果您使用简单的基本绘图函数(我在代码中添加了注释),就不会有任何问题,而且工作正常!可悲的是,我需要在我的应用程序,因为基本情节是丑陋的。我看到了一些建议,用于解决这个问题,但我不知道在哪里应该把隔离()来解决我的问题,也没有意义使用隔离()时,基本情节函数工作正常,没有它,它是ggploit,使问题。如有任何解释,将不胜感激。
如果您遵循ggplot传递列名的首选方法,即使用,似乎效果不错。数据
。
library(ggplot2)
library(shiny)
server <- function(input, output, session) {
df <- reactive({
cars %>% dplyr::select(!!!input$variables, input$outvar)
})
plt <- eventReactive(input$run, {
#Just creating lm formula
current_formula <- paste0(input$outvar, " ~ ", paste0(input$variables, collapse = " + "))
current_formula <- as.formula(current_formula)
#Fitting lm
fit <- lm(current_formula, data = df())
pred <- predict(fit, newdata = df())
#Plotting
ggplot(df(), aes(.data[[input$outvar]], pred)) +
labs(x = "Observed", y = "Predicted") +
geom_point() +
theme_bw()
})
output$plot <- renderPlot({
plt()
})
}
# Run the application
shinyApp(ui = ui, server = server)
我认为问题是ggplod
在懒惰地处理事情。如果您对代码做了一次更改,以预拉df()
和输入$outvar
,则过度反应是固定的:
plt <- eventReactive(input$run, {
#Just creating lm formula
current_formula <- paste0(input$outvar, " ~ ", paste0(input$variables, collapse = " + "))
current_formula <- as.formula(current_formula)
#Fitting lm
fit <- lm(current_formula, data = df())
pred <- predict(fit, newdata = df())
#Plotting
dat <- df()
outv <- input$outvar
ggplot(dat, aes(dat[, outv], pred)) +
labs(x = "Observed", y = "Predicted") +
geom_point() +
theme_bw()
#plot(df()[, input$outvar], pred) #This one works fine!!!!
})
问题是ggplod
以某种方式在内部保留了一些反应性。
(我把赋值放在dat
和outv
的前面,只是为了演示。更明智的做法可能是在eventReactive
块中首先分配它们,并对所有内容使用dat
,只是为了代码的一致性(其他代码都没有在懒惰原则上运行)。